Browse code

* Added filter_body function (not tested yet due to broken trunk).

git-svn-id: https://openser.svn.sourceforge.net/svnroot/openser/trunk@2881 689a6050-402a-0410-94f2-e92a70836424

Juha Heinanen authored on 08/10/2007 07:52:22
Showing 3 changed files
... ...
@@ -1,3 +1,4 @@
1
+
1 2
 textops Module
2 3
 
3 4
 Andrei Pelinescu-Onciul
... ...
@@ -11,7 +12,7 @@ Andrei Pelinescu-Onciul
11 12
 Daniel-Constantin Mierla
12 13
 
13 14
    Copyright � 2003 FhG FOKUS
14
-     __________________________________________________________
15
+     _________________________________________________________
15 16
 
16 17
    Table of Contents
17 18
    1. User's Guide
... ...
@@ -39,18 +40,19 @@ Daniel-Constantin Mierla
39 40
               1.3.10. subst_uri('/re/repl/flags')
40 41
               1.3.11. subst_user('/re/repl/flags')
41 42
               1.3.12. subst_body('/re/repl/flags')
42
-              1.3.13. append_to_reply(txt)
43
-              1.3.14. append_hf(txt)
44
-              1.3.15. append_hf(txt, hdr)
45
-              1.3.16. insert_hf(txt)
46
-              1.3.17. insert_hf(txt, hdr)
47
-              1.3.18. append_urihf(prefix, suffix)
48
-              1.3.19. is_present_hf(hf_name)
49
-              1.3.20. append_time()
50
-              1.3.21. is_method(name)
51
-              1.3.22. remove_hf(hname)
52
-              1.3.23. has_body(), has_body(mime)
53
-              1.3.24. is_privacy(privacy_type)
43
+              1.3.13. filter_body(content_type)
44
+              1.3.14. append_to_reply(txt)
45
+              1.3.15. append_hf(txt)
46
+              1.3.16. append_hf(txt, hdr)
47
+              1.3.17. insert_hf(txt)
48
+              1.3.18. insert_hf(txt, hdr)
49
+              1.3.19. append_urihf(prefix, suffix)
50
+              1.3.20. is_present_hf(hf_name)
51
+              1.3.21. append_time()
52
+              1.3.22. is_method(name)
53
+              1.3.23. remove_hf(hname)
54
+              1.3.24. has_body(), has_body(mime)
55
+              1.3.25. is_privacy(privacy_type)
54 56
 
55 57
         1.4. Known Limitations
56 58
 
... ...
@@ -70,19 +72,20 @@ Daniel-Constantin Mierla
70 72
    1-10. subst_uri usage
71 73
    1-11. subst usage
72 74
    1-12. subst_body usage
73
-   1-13. append_to_reply usage
74
-   1-14. append_hf usage
75
+   1-13. filter_body usage
76
+   1-14. append_to_reply usage
75 77
    1-15. append_hf usage
76
-   1-16. insert_hf usage
78
+   1-16. append_hf usage
77 79
    1-17. insert_hf usage
78
-   1-18. append_urihf usage
79
-   1-19. is_present_hf usage
80
-   1-20. append_time usage
81
-   1-21. is_method usage
82
-   1-22. remove_hf usage
83
-   1-23. has_body usage
84
-   1-24. is_privacy usage
85
-     __________________________________________________________
80
+   1-18. insert_hf usage
81
+   1-19. append_urihf usage
82
+   1-20. is_present_hf usage
83
+   1-21. append_time usage
84
+   1-22. is_method usage
85
+   1-23. remove_hf usage
86
+   1-24. has_body usage
87
+   1-25. is_privacy usage
88
+     _________________________________________________________
86 89
 
87 90
 Chapter 1. User's Guide
88 91
 
... ...
@@ -94,7 +97,7 @@ Chapter 1. User's Guide
94 97
    manipulate the message at text level, e.g., regular expression
95 98
    search and replace, Perl-like substitutions, checks for method
96 99
    type, header presence, insert of new header and date, etc.
97
-     __________________________________________________________
100
+     _________________________________________________________
98 101
 
99 102
 1.1.1. Known Limitations
100 103
 
... ...
@@ -103,7 +106,7 @@ Chapter 1. User's Guide
103 106
    header field:
104 107
 From: medabeda
105 108
  <sip:medameda@foo.bar>;tag=1234
106
-     __________________________________________________________
109
+     _________________________________________________________
107 110
 
108 111
 1.2. Dependencies
109 112
 
... ...
@@ -112,7 +115,7 @@ From: medabeda
112 115
    The following modules must be loaded before this module:
113 116
 
114 117
      * No dependencies on other OpenSER modules.
115
-     __________________________________________________________
118
+     _________________________________________________________
116 119
 
117 120
 1.2.2. External Libraries or Applications
118 121
 
... ...
@@ -120,7 +123,7 @@ From: medabeda
120 123
    before running OpenSER with this module loaded:
121 124
 
122 125
      * None.
123
-     __________________________________________________________
126
+     _________________________________________________________
124 127
 
125 128
 1.3. Exported Functions
126 129
 
... ...
@@ -139,7 +142,7 @@ From: medabeda
139 142
 ...
140 143
 if ( search("[Ss][Ii][Pp]") ) { /*....*/ };
141 144
 ...
142
-     __________________________________________________________
145
+     _________________________________________________________
143 146
 
144 147
 1.3.2. search_body(re)
145 148
 
... ...
@@ -156,7 +159,7 @@ if ( search("[Ss][Ii][Pp]") ) { /*....*/ };
156 159
 ...
157 160
 if ( search_body("[Ss][Ii][Pp]") ) { /*....*/ };
158 161
 ...
159
-     __________________________________________________________
162
+     _________________________________________________________
160 163
 
161 164
 1.3.3. search_append(re, txt)
162 165
 
... ...
@@ -174,7 +177,7 @@ if ( search_body("[Ss][Ii][Pp]") ) { /*....*/ };
174 177
 ...
175 178
 search_append("[Oo]pen[Ss]er", " SIP Proxy");
176 179
 ...
177
-     __________________________________________________________
180
+     _________________________________________________________
178 181
 
179 182
 1.3.4. search_append_body(re, txt)
180 183
 
... ...
@@ -193,7 +196,7 @@ search_append("[Oo]pen[Ss]er", " SIP Proxy");
193 196
 ...
194 197
 search_append_body("[Oo]pen[Ss]er", " SIP Proxy");
195 198
 ...
196
-     __________________________________________________________
199
+     _________________________________________________________
197 200
 
198 201
 1.3.5. replace(re, txt)
199 202
 
... ...
@@ -211,7 +214,7 @@ search_append_body("[Oo]pen[Ss]er", " SIP Proxy");
211 214
 ...
212 215
 replace("openser", "OpenSER SIP Proxy");
213 216
 ...
214
-     __________________________________________________________
217
+     _________________________________________________________
215 218
 
216 219
 1.3.6. replace_body(re, txt)
217 220
 
... ...
@@ -230,7 +233,7 @@ replace("openser", "OpenSER SIP Proxy");
230 233
 ...
231 234
 replace_body("openser", "OpenSER SIP Proxy");
232 235
 ...
233
-     __________________________________________________________
236
+     _________________________________________________________
234 237
 
235 238
 1.3.7. replace_all(re, txt)
236 239
 
... ...
@@ -248,7 +251,7 @@ replace_body("openser", "OpenSER SIP Proxy");
248 251
 ...
249 252
 replace_all("openser", "OpenSER SIP Proxy");
250 253
 ...
251
-     __________________________________________________________
254
+     _________________________________________________________
252 255
 
253 256
 1.3.8. replace_body_all(re, txt)
254 257
 
... ...
@@ -267,7 +270,7 @@ replace_all("openser", "OpenSER SIP Proxy");
267 270
 ...
268 271
 replace_body_all("openser", "OpenSER SIP Proxy");
269 272
 ...
270
-     __________________________________________________________
273
+     _________________________________________________________
271 274
 
272 275
 1.3.9. subst('/re/repl/flags')
273 276
 
... ...
@@ -291,13 +294,13 @@ replace_body_all("openser", "OpenSER SIP Proxy");
291 294
 # replace the uri in to: with the message uri (just an example)
292 295
 if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1\u\2/ig') ) {};
293 296
 
294
-# replace the uri in to: with the value of avp sip_address (just an exam
295
-ple)
296
-if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1$avp(sip_address)\
297
-2/ig') ) {};
297
+# replace the uri in to: with the value of avp sip_address (just an exa
298
+mple)
299
+if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1$avp(sip_address)
300
+\2/ig') ) {};
298 301
 
299 302
 ...
300
-     __________________________________________________________
303
+     _________________________________________________________
301 304
 
302 305
 1.3.10. subst_uri('/re/repl/flags')
303 306
 
... ...
@@ -319,23 +322,24 @@ if ( subst('/^To:(.*)sip:[^@]*@[a-zA-Z0-9.]+(.*)$/t:\1$avp(sip_address)\
319 322
 
320 323
    Example 1-10. subst_uri usage
321 324
 ...
322
-# adds 3463 prefix to numeric uris, and save the original uri (\0 match)
325
+# adds 3463 prefix to numeric uris, and save the original uri (\0 match
326
+)
323 327
 # as a parameter: orig_uri (just an example)
324 328
 if (subst_uri('/^sip:([0-9]+)@(.*)$/sip:3463\1@\2;orig_uri=\0/i')){$
325 329
 
326
-# adds the avp 'uri_prefix' as prefix to numeric uris, and save the orig
327
-inal
330
+# adds the avp 'uri_prefix' as prefix to numeric uris, and save the ori
331
+ginal
328 332
 # uri (\0 match) as a parameter: orig_uri (just an example)
329
-if (subst_uri('/^sip:([0-9]+)@(.*)$/sip:$avp(uri_prefix)\1@\2;orig_uri=\
330
-0/i')){$
333
+if (subst_uri('/^sip:([0-9]+)@(.*)$/sip:$avp(uri_prefix)\1@\2;orig_uri=
334
+\0/i')){$
331 335
 
332 336
 ...
333
-     __________________________________________________________
337
+     _________________________________________________________
334 338
 
335 339
 1.3.11. subst_user('/re/repl/flags')
336 340
 
337
-   Runs the re substitution on the message uri (like subst_uri but
338
-   works only on the user portion of the uri)
341
+   Runs the re substitution on the message uri (like subst_uri
342
+   but works only on the user portion of the uri)
339 343
 
340 344
    Meaning of the parameters is as follows:
341 345
 
... ...
@@ -356,11 +360,12 @@ if (subst_uri('/^sip:([0-9]+)@(.*)$/sip:$avp(uri_prefix)\1@\2;orig_uri=\
356 360
 if (subst_user('/3642$/36423463/')){$
357 361
 
358 362
 ...
359
-# adds avp 'user_prefix' as prefix to username in r-uri ending with 3642
363
+# adds avp 'user_prefix' as prefix to username in r-uri ending with 364
364
+2
360 365
 if (subst_user('/(.*)3642$/$avp(user_prefix)\13642/')){$
361 366
 
362 367
 ...
363
-     __________________________________________________________
368
+     _________________________________________________________
364 369
 
365 370
 1.3.12. subst_body('/re/repl/flags')
366 371
 
... ...
@@ -385,9 +390,33 @@ if (subst_user('/(.*)3642$/$avp(user_prefix)\13642/')){$
385 390
 if ( subst_body('/^o=(.*) /o=$fU ') ) {};
386 391
 
387 392
 ...
388
-     __________________________________________________________
393
+     _________________________________________________________
394
+
395
+1.3.13. filter_body(content_type)
396
+
397
+   Filters multipart body by leaving out all other body parts
398
+   except the first body part of given type.
399
+
400
+   Meaning of the parameters is as follows:
389 401
 
390
-1.3.13. append_to_reply(txt)
402
+     * content_type - Content type to be left in the body.
403
+
404
+   This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
405
+   FAILURE_ROUTE, BRANCH_ROUTE.
406
+
407
+   Example 1-13. filter_body usage
408
+...
409
+if (has_body("multipart/mixed")) {
410
+    if (filter_body("application/sdp") {
411
+        $cT = "application/sdp";
412
+    } else {
413
+        xlog("Body part application/sdp not found\n");
414
+    }
415
+}
416
+...
417
+     _________________________________________________________
418
+
419
+1.3.14. append_to_reply(txt)
391 420
 
392 421
    Append txt as header to the reply.
393 422
 
... ...
@@ -398,14 +427,14 @@ if ( subst_body('/^o=(.*) /o=$fU ') ) {};
398 427
    This function can be used from REQUEST_ROUTE, BRANCH_ROUTE,
399 428
    ERROR_ROUTE.
400 429
 
401
-   Example 1-13. append_to_reply usage
430
+   Example 1-14. append_to_reply usage
402 431
 ...
403 432
 append_to_reply("Foo: bar\r\n");
404 433
 append_to_reply("Foo: $rm at $Ts\r\n");
405 434
 ...
406
-     __________________________________________________________
435
+     _________________________________________________________
407 436
 
408
-1.3.14. append_hf(txt)
437
+1.3.15. append_hf(txt)
409 438
 
410 439
    Appends 'txt' as header after the last header field.
411 440
 
... ...
@@ -415,22 +444,22 @@ append_to_reply("Foo: $rm at $Ts\r\n");
415 444
        pseudo-variables which will be replaced at run time.
416 445
 
417 446
    Note: Headers which are added in main route cannot be removed
418
-   in further routes (e.g. failure routes). So, the idea is not to
419
-   add there any headers that you might want to remove later. To
420
-   add headers temporarely use the branch route because the
447
+   in further routes (e.g. failure routes). So, the idea is not
448
+   to add there any headers that you might want to remove later.
449
+   To add headers temporarely use the branch route because the
421 450
    changes you do there are per-branch.
422 451
 
423 452
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
424 453
    FAILURE_ROUTE, BRANCH_ROUTE.
425 454
 
426
-   Example 1-14. append_hf usage
455
+   Example 1-15. append_hf usage
427 456
 ...
428 457
 append_hf("P-hint: VOICEMAIL\r\n");
429 458
 append_hf("From-username: $fU\r\n");
430 459
 ...
431
-     __________________________________________________________
460
+     _________________________________________________________
432 461
 
433
-1.3.15. append_hf(txt, hdr)
462
+1.3.16. append_hf(txt, hdr)
434 463
 
435 464
    Appends 'txt' as header after first 'hdr' header field.
436 465
 
... ...
@@ -443,14 +472,14 @@ append_hf("From-username: $fU\r\n");
443 472
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
444 473
    FAILURE_ROUTE, BRANCH_ROUTE.
445 474
 
446
-   Example 1-15. append_hf usage
475
+   Example 1-16. append_hf usage
447 476
 ...
448 477
 append_hf("P-hint: VOICEMAIL\r\n", "Call-ID");
449 478
 append_hf("From-username: $fU\r\n", "Call-ID");
450 479
 ...
451
-     __________________________________________________________
480
+     _________________________________________________________
452 481
 
453
-1.3.16. insert_hf(txt)
482
+1.3.17. insert_hf(txt)
454 483
 
455 484
    Inserts 'txt' as header before the first header field.
456 485
 
... ...
@@ -462,14 +491,14 @@ append_hf("From-username: $fU\r\n", "Call-ID");
462 491
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
463 492
    FAILURE_ROUTE, BRANCH_ROUTE.
464 493
 
465
-   Example 1-16. insert_hf usage
494
+   Example 1-17. insert_hf usage
466 495
 ...
467 496
 insert_hf("P-hint: VOICEMAIL\r\n");
468 497
 insert_hf("To-username: $tU\r\n");
469 498
 ...
470
-     __________________________________________________________
499
+     _________________________________________________________
471 500
 
472
-1.3.17. insert_hf(txt, hdr)
501
+1.3.18. insert_hf(txt, hdr)
473 502
 
474 503
    Inserts 'txt' as header before first 'hdr' header field.
475 504
 
... ...
@@ -482,14 +511,14 @@ insert_hf("To-username: $tU\r\n");
482 511
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
483 512
    FAILURE_ROUTE, BRANCH_ROUTE.
484 513
 
485
-   Example 1-17. insert_hf usage
514
+   Example 1-18. insert_hf usage
486 515
 ...
487 516
 insert_hf("P-hint: VOICEMAIL\r\n", "Call-ID");
488 517
 insert_hf("To-username: $tU\r\n", "Call-ID");
489 518
 ...
490
-     __________________________________________________________
519
+     _________________________________________________________
491 520
 
492
-1.3.18. append_urihf(prefix, suffix)
521
+1.3.19. append_urihf(prefix, suffix)
493 522
 
494 523
    Append header field name with original Request-URI in middle.
495 524
 
... ...
@@ -501,20 +530,20 @@ insert_hf("To-username: $tU\r\n", "Call-ID");
501 530
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
502 531
    BRANCH_ROUTE.
503 532
 
504
-   Example 1-18. append_urihf usage
533
+   Example 1-19. append_urihf usage
505 534
 ...
506 535
 append_urihf("CC-Diversion: ", "\r\n");
507 536
 ...
508
-     __________________________________________________________
537
+     _________________________________________________________
509 538
 
510
-1.3.19. is_present_hf(hf_name)
539
+1.3.20. is_present_hf(hf_name)
511 540
 
512 541
    Return true if a header field is present in message.
513 542
 
514 543
    Note
515 544
 
516
-        The function is also able to distinguish the compact names. For
517
-        exmaple "From" will match with "f"
545
+   The function is also able to distinguish the compact names.
546
+   For exmaple "From" will match with "f"
518 547
 
519 548
    Meaning of the parameters is as follows:
520 549
 
... ...
@@ -523,18 +552,18 @@ append_urihf("CC-Diversion: ", "\r\n");
523 552
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
524 553
    FAILURE_ROUTE, BRANCH_ROUTE.
525 554
 
526
-   Example 1-19. is_present_hf usage
555
+   Example 1-20. is_present_hf usage
527 556
 ...
528 557
 if (is_present_hf("From")) log(1, "From HF Present");
529 558
 ...
530
-     __________________________________________________________
559
+     _________________________________________________________
531 560
 
532
-1.3.20. append_time()
561
+1.3.21. append_time()
533 562
 
534
-   Adds a time header to the reply of the request. You must use it
535
-   before functions that are likely to send a reply, e.g., save()
536
-   from 'registrar' module. Header format is: "Date: %a, %d %b %Y
537
-   %H:%M:%S GMT", with the legend:
563
+   Adds a time header to the reply of the request. You must use
564
+   it before functions that are likely to send a reply, e.g.,
565
+   save() from 'registrar' module. Header format is: "Date: %a,
566
+   %d %b %Y %H:%M:%S GMT", with the legend:
538 567
 
539 568
      * %a abbreviated week of day name (locale)
540 569
      * %d day of month as decimal number
... ...
@@ -549,16 +578,16 @@ if (is_present_hf("From")) log(1, "From HF Present");
549 578
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE,
550 579
    BRANCH_ROUTE.
551 580
 
552
-   Example 1-20. append_time usage
581
+   Example 1-21. append_time usage
553 582
 ...
554 583
 append_time();
555 584
 ...
556
-     __________________________________________________________
585
+     _________________________________________________________
557 586
 
558
-1.3.21. is_method(name)
587
+1.3.22. is_method(name)
559 588
 
560
-   Check if the method of the message matches the name. If name is
561
-   a known method (invite, cancel, ack, bye, options, info,
589
+   Check if the method of the message matches the name. If name
590
+   is a known method (invite, cancel, ack, bye, options, info,
562 591
    update, register, message, subscribe, notify, refer, prack),
563 592
    the function performs method ID testing (integer comparison)
564 593
    instead of ignore case string comparison.
... ...
@@ -581,7 +610,7 @@ append_time();
581 610
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
582 611
    FAILURE_ROUTE, and BRANCH_ROUTE.
583 612
 
584
-   Example 1-21. is_method usage
613
+   Example 1-22. is_method usage
585 614
 ...
586 615
 if(is_method("INVITE"))
587 616
 {
... ...
@@ -592,9 +621,9 @@ if(is_method("OPTION|UPDATE"))
592 621
     # process OPTIONs and UPDATEs here
593 622
 }
594 623
 ...
595
-     __________________________________________________________
624
+     _________________________________________________________
596 625
 
597
-1.3.22. remove_hf(hname)
626
+1.3.23. remove_hf(hname)
598 627
 
599 628
    Remove from message all headers with name "hname"
600 629
 
... ...
@@ -607,23 +636,23 @@ if(is_method("OPTION|UPDATE"))
607 636
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
608 637
    FAILURE_ROUTE and BRANCH_ROUTE.
609 638
 
610
-   Example 1-22. remove_hf usage
639
+   Example 1-23. remove_hf usage
611 640
 ...
612 641
 if(remove_hf("User-Agent"))
613 642
 {
614 643
     # User Agent header removed
615 644
 }
616 645
 ...
617
-     __________________________________________________________
646
+     _________________________________________________________
618 647
 
619
-1.3.23. has_body(), has_body(mime)
648
+1.3.24. has_body(), has_body(mime)
620 649
 
621 650
    The function returns true if the SIP message has a body
622
-   attached. The checked includes also the "Content-Lenght" header
623
-   presence and value.
651
+   attached. The checked includes also the "Content-Lenght"
652
+   header presence and value.
624 653
 
625
-   If a paramter is given, the mime described will be also checked
626
-   against the "Content-Type" header.
654
+   If a paramter is given, the mime described will be also
655
+   checked against the "Content-Type" header.
627 656
 
628 657
    Meaning of the parameters is as follows:
629 658
 
... ...
@@ -633,16 +662,16 @@ if(remove_hf("User-Agent"))
633 662
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
634 663
    FAILURE_ROUTE and BRANCH_ROUTE.
635 664
 
636
-   Example 1-23. has_body usage
665
+   Example 1-24. has_body usage
637 666
 ...
638 667
 if(has_body("application/sdp"))
639 668
 {
640 669
     # do interesting stuff here
641 670
 }
642 671
 ...
643
-     __________________________________________________________
672
+     _________________________________________________________
644 673
 
645
-1.3.24. is_privacy(privacy_type)
674
+1.3.25. is_privacy(privacy_type)
646 675
 
647 676
    The function returns true if the SIP message has a Privacy
648 677
    header field that includes the given privacy_type among its
... ...
@@ -653,27 +682,27 @@ if(has_body("application/sdp"))
653 682
    This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE,
654 683
    FAILURE_ROUTE and BRANCH_ROUTE.
655 684
 
656
-   Example 1-24. is_privacy usage
685
+   Example 1-25. is_privacy usage
657 686
 ...
658 687
 if(is_privacy("id"))
659 688
 {
660 689
     # do interesting stuff here
661 690
 }
662 691
 ...
663
-     __________________________________________________________
692
+     _________________________________________________________
664 693
 
665 694
 1.4. Known Limitations
666 695
 
667 696
    Search functions are applied to the original request, i.e.,
668 697
    they ignore all changes resulting from message processing in
669 698
    OpenSER script.
670
-     __________________________________________________________
699
+     _________________________________________________________
671 700
 
672 701
 Chapter 2. Developer's Guide
673 702
 
674 703
    The module does not provide any API to use in other OpenSER
675 704
    modules.
676
-     __________________________________________________________
705
+     _________________________________________________________
677 706
 
678 707
 Chapter 3. Frequently Asked Questions
679 708
 
... ...
@@ -687,8 +716,8 @@ Chapter 3. Frequently Asked Questions
687 716
 
688 717
    3.2. Where can I post a question about this module?
689 718
 
690
-   First at all check if your question was already answered on one
691
-   of our mailing lists:
719
+   First at all check if your question was already answered on
720
+   one of our mailing lists:
692 721
 
693 722
      * User Mailing List -
694 723
        http://openser.org/cgi-bin/mailman/listinfo/users
... ...
@@ -492,6 +492,42 @@ if (subst_user('/(.*)3642$/$avp(user_prefix)\13642/')){$
492 492
 ...
493 493
 if ( subst_body('/^o=(.*) /o=$fU ') ) {};
494 494
 
495
+...
496
+</programlisting>
497
+		</example>
498
+	</section>
499
+
500
+	<section>
501
+		<title>
502
+		<function moreinfo="none">filter_body(content_type)</function>
503
+		</title>
504
+		<para>
505
+		Filters multipart body by leaving out all other body
506
+		parts except the first body part of given type.
507
+		</para>
508
+		<para>Meaning of the parameters is as follows:</para>
509
+		<itemizedlist>
510
+		<listitem>
511
+			<para><emphasis>content_type</emphasis> -
512
+				Content type to be left in the body.
513
+			</para>
514
+		</listitem>
515
+		</itemizedlist>
516
+		<para>
517
+		This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, 
518
+		FAILURE_ROUTE, BRANCH_ROUTE.
519
+		</para>
520
+		<example>
521
+		<title><function>filter_body</function> usage</title>
522
+		<programlisting format="linespecific">
523
+...
524
+if (has_body("multipart/mixed")) {
525
+    if (filter_body("application/sdp") {
526
+        $cT = "application/sdp";
527
+    } else {
528
+        xlog("Body part application/sdp not found\n");
529
+    }
530
+}
495 531
 ...
496 532
 </programlisting>
497 533
 		</example>
... ...
@@ -95,6 +95,7 @@ static int subst_f(struct sip_msg*, char*, char*);
95 95
 static int subst_uri_f(struct sip_msg*, char*, char*);
96 96
 static int subst_user_f(struct sip_msg*, char*, char*);
97 97
 static int subst_body_f(struct sip_msg*, char*, char*);
98
+static int filter_body_f(struct sip_msg*, char*, char*);
98 99
 static int remove_hf_f(struct sip_msg* msg, char* str_hf, char* foo);
99 100
 static int is_present_hf_f(struct sip_msg* msg, char* str_hf, char* foo);
100 101
 static int search_append_f(struct sip_msg*, char*, char*);
... ...
@@ -171,6 +172,8 @@ static cmd_export_t cmds[]={
171 172
 			REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
172 173
 	{"subst_body",       subst_body_f,      1, fixup_substre, 0,
173 174
 			REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
175
+	{"filter_body",      filter_body_f,     1, str_fixup, 0,
176
+			REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE},
174 177
 	{"append_time",      append_time_f,     0, 0, 0,
175 178
 			REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
176 179
 	{"is_method",        is_method_f,       1, fixup_method, 0,
... ...
@@ -711,6 +714,97 @@ error:
711 714
 }
712 715
 
713 716
 
717
+static inline int find_line_start(char *text, unsigned int text_len,
718
+				  char **buf, unsigned int *buf_len)
719
+{
720
+    char *ch, *start;
721
+    unsigned int len;
722
+
723
+    start = *buf;
724
+    len = *buf_len;
725
+
726
+    while (text_len <= len) {
727
+	if (strncmp(text, start, text_len) == 0) {
728
+	    *buf = start;
729
+	    *buf_len = len;
730
+	    return 1;
731
+	}
732
+	if ((ch = memchr(start, 13, len - 1))) {
733
+	    if (*(ch + 1) != 10) {
734
+		LM_ERR("No LF after CR\n");
735
+		return 0;
736
+	    }
737
+	    len = len - (ch - start + 2);
738
+	    start = ch + 2;
739
+	} else {
740
+	    LM_ERR("No CRLF found\n");
741
+	    return 0;
742
+	}
743
+    }
744
+    return 0;
745
+}
746
+
747
+
748
+/* Filters multipart body by leaving out everything else except
749
+ * first body part of given content type. */
750
+static int filter_body_f(struct sip_msg* msg, char* _content_type,
751
+			 char* ignored)
752
+{
753
+	char *start;
754
+	unsigned int len;
755
+	str *content_type, body;
756
+
757
+	body.s = get_body(msg);
758
+	if (body.s == 0) {
759
+		LM_ERR("Failed to get the message body\n");
760
+		return -1;
761
+	}
762
+	body.len = msg->len - (int)(body.s - msg->buf);
763
+	if (body.len == 0) {
764
+		LM_DBG("Message body has zero length\n");
765
+		return -1;
766
+	}
767
+	
768
+	content_type = (str *)_content_type;
769
+	start = body.s;
770
+	len = body.len;
771
+	
772
+	while (find_line_start("Content-Type: ", 14, &start, &len)) {
773
+	    start = start + 14;
774
+	    len = len - 14;
775
+	    if (len > content_type->len + 2) {
776
+		if (strncasecmp(start, content_type->s, content_type->len)
777
+		    == 0) {
778
+		    start = start + content_type->len;
779
+		    if ((*start != 13) || (*(start + 1) != 10)) {
780
+			LM_ERR("No CRLF found after content type\n");
781
+			return -1;
782
+		    }
783
+		    start = start + 2;
784
+		    len = len - content_type->len - 2;
785
+		    if (del_lump(msg, body.s - msg->buf, start - body.s, 0)
786
+			== 0) {
787
+			LM_ERR("Deleting lump failed\n");
788
+			return -1;
789
+		    }
790
+		    if (find_line_start("--Boundary", 10, &start, &len)) {
791
+			if (del_lump(msg, start - msg->buf, len, 0) == 0) {
792
+			    LM_ERR("Deleting lump failed\n");
793
+			    return -1;
794
+			}
795
+		    } else {
796
+			LM_ERR("Boundary not found after content\n");
797
+			return -1;
798
+		    }
799
+		}
800
+	    } else {
801
+		return -1;
802
+	    }
803
+	}
804
+	return -1;
805
+}
806
+
807
+
714 808
 static int remove_hf_f(struct sip_msg* msg, char* str_hf, char* foo)
715 809
 {
716 810
 	struct hdr_field *hf;