Browse code

core, lib, modules: restructured source code tree

- new folder src/ to hold the source code for main project applications
- main.c is in src/
- all core files are subfolder are in src/core/
- modules are in src/modules/
- libs are in src/lib/
- application Makefiles are in src/
- application binary is built in src/ (src/kamailio)

Daniel-Constantin Mierla authored on 07/12/2016 11:03:51
Showing 1 changed files
1 1
deleted file mode 100644
... ...
@@ -1,587 +0,0 @@
1
-/*
2
- * Copyright (C) 2008 iptelorg GmbH
3
- *
4
- * This file is part of Kamailio, a free SIP server.
5
- *
6
- * Kamailio is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License as published by
8
- * the Free Software Foundation; either version 2 of the License, or
9
- * (at your option) any later version
10
- *
11
- * Kamailio is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
- * GNU General Public License for more details.
15
- *
16
- * You should have received a copy of the GNU General Public License 
17
- * along with this program; if not, write to the Free Software 
18
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
19
- *
20
- */
21
-
22
-/*! \file
23
- * \brief Parser :: Body handling
24
- *
25
- * \ingroup parser
26
- */
27
-
28
-
29
-#include "../trim.h"
30
-#include "parser_f.h"
31
-#include "parse_content.h"
32
-#include "parse_param.h"
33
-#include "keys.h"
34
-#include "parse_body.h"
35
-
36
-/*! \brief returns the value of boundary parameter from the Contect-Type HF */
37
-static inline int get_boundary_param(struct sip_msg *msg, str *boundary)
38
-{
39
-	str	s;
40
-	char	*c;
41
-	param_t	*p, *list;
42
-
43
-#define is_boundary(c) \
44
-	(((c)[0] == 'b' || (c)[0] == 'B') && \
45
-	((c)[1] == 'o' || (c)[1] == 'O') && \
46
-	((c)[2] == 'u' || (c)[2] == 'U') && \
47
-	((c)[3] == 'n' || (c)[3] == 'N') && \
48
-	((c)[4] == 'd' || (c)[4] == 'D') && \
49
-	((c)[5] == 'a' || (c)[5] == 'A') && \
50
-	((c)[6] == 'r' || (c)[6] == 'R') && \
51
-	((c)[7] == 'y' || (c)[7] == 'Y'))
52
-
53
-#define boundary_param_len (sizeof("boundary")-1)
54
-
55
-	/* get the pointer to the beginning of the parameter list */
56
-	s.s = msg->content_type->body.s;
57
-	s.len = msg->content_type->body.len;
58
-	c = find_not_quoted(&s, ';');
59
-	if (!c)
60
-		return -1;
61
-	c++;
62
-	s.len = s.len - (c - s.s);
63
-	s.s = c;
64
-	trim_leading(&s);
65
-
66
-	if (s.len <= 0)
67
-		return -1;
68
-
69
-	/* parse the parameter list, and search for boundary */
70
-	if (parse_params(&s, CLASS_ANY, NULL, &list)<0)
71
-		return -1;
72
-
73
-	boundary->s = NULL;
74
-	for (p = list; p; p = p->next)
75
-		if ((p->name.len == boundary_param_len) &&
76
-			is_boundary(p->name.s)
77
-		) {
78
-			boundary->s = p->body.s;
79
-			boundary->len = p->body.len;
80
-			break;
81
-		}
82
-	free_params(list);
83
-	if (!boundary->s || !boundary->len)
84
-		return -1;
85
-
86
-	DBG("boundary is \"%.*s\"\n",
87
-		boundary->len, boundary->s);
88
-	return 0;
89
-}
90
-
91
-/*! \brief search the next boundary in the buffer */
92
-static inline char *search_boundary(char *buf, char *buf_end, str *boundary)
93
-{
94
-	char *c;
95
-
96
-	c = buf;
97
-	while (c + 2 /* -- */ + boundary->len < buf_end) {
98
-		if ((*c == '-') && (*(c+1) == '-') &&
99
-			(memcmp(c+2, boundary->s, boundary->len) == 0)
100
-		)
101
-			return c; /* boundary found */
102
-
103
-		/* go to the next line */
104
-		while ((c < buf_end) && (*c != '\n')) c++;
105
-		c++;
106
-	}
107
-	return NULL;
108
-}
109
-
110
-/*! \brief extract the body of a part from a multipart SIP msg body */
111
-inline static char *get_multipart_body(char *buf,
112
-					char *buf_end,
113
-					str *boundary,
114
-					int *len)
115
-{
116
-	char *beg, *end;
117
-
118
-	if (buf >= buf_end)
119
-		goto error;
120
-
121
-	beg = buf;
122
-	while ((*beg != '\r') && (*beg != '\n')) {
123
-		while ((beg < buf_end) && (*beg != '\n'))
124
-			beg++;
125
-		beg++;
126
-		if (beg >= buf_end)
127
-			goto error;
128
-	}
129
-	/* CRLF delimeter found, the body begins right after it */
130
-	while ((beg < buf_end) && (*beg != '\n'))
131
-		beg++;
132
-	beg++;
133
-	if (beg >= buf_end)
134
-		goto error;
135
-
136
-	if (!(end = search_boundary(beg, buf_end, boundary)))
137
-		goto error;
138
-
139
-	/* CRLF preceding the boundary belongs to the boundary
140
-	and not to the body */
141
-	if (*(end-1) == '\n') end--;
142
-	if (*(end-1) == '\r') end--;
143
-
144
-	if (end < beg)
145
-		goto error;
146
-
147
-	*len = end-beg;
148
-	return beg;
149
-error:
150
-	ERR("failed to extract the body from the multipart mime type\n");
151
-	return NULL;
152
-}
153
-
154
-
155
-/*! \brief macros from parse_hname2.c */
156
-#define READ(val) \
157
-(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
158
-
159
-#define LOWER_DWORD(d) ((d) | 0x20202020)
160
-
161
-/*! \brief Returns the pointer within the msg body to the given type/subtype,
162
- * and sets the length of the body part.
163
- * The result can be the whole msg body, or a part of a multipart body.
164
- */
165
-char *get_body_part(	struct sip_msg *msg,
166
-			unsigned short type, unsigned short subtype,
167
-			int *len)
168
-{
169
-	int	mime;
170
-	unsigned int	umime;
171
-	char	*c, *c2, *buf_end;
172
-	str	boundary;
173
-
174
-#define content_type_len \
175
-	(sizeof("Content-Type") - 1)
176
-
177
-	if ((mime = parse_content_type_hdr(msg)) <= 0)
178
-		return NULL;
179
-
180
-	if (mime == ((type<<16)|subtype)) {
181
-		/* content-type is type/subtype */
182
-		c = get_body(msg);
183
-		if (c)
184
-			*len = msg->buf+msg->len - c;
185
-		return c;
186
-
187
-	} else if ((mime>>16) == TYPE_MULTIPART) {
188
-		/* type is multipart/something, search for type/subtype part */
189
-
190
-		if (get_boundary_param(msg, &boundary)) {
191
-			ERR("failed to get boundary parameter\n");
192
-			return NULL;
193
-		}
194
-		if (!(c = get_body(msg)))
195
-			return NULL;
196
-		buf_end = msg->buf+msg->len;
197
-
198
-		/* check all the body parts delimated by the boundary value,
199
-		and search for the Content-Type HF with the given 
200
-		type/subtype */
201
-next_part:
202
-		while ((c = search_boundary(c, buf_end, &boundary))) {
203
-			/* skip boundary */
204
-			c += 2 + boundary.len;
205
-
206
-			if ((c+2 > buf_end) ||
207
-				((*c == '-') && (*(c+1) == '-'))
208
-			)
209
-				/* end boundary, no more body part
210
-				will follow */
211
-				return NULL;
212
-
213
-			/* go to the next line */
214
-			while ((c < buf_end) && (*c != '\n')) c++;
215
-			c++;
216
-			if (c >= buf_end)
217
-				return NULL;
218
-
219
-			/* try to find the content-type header */
220
-			while ((*c != '\r') && (*c != '\n')) {
221
-				if (c + content_type_len >= buf_end)
222
-					return NULL;
223
-
224
-				if ((LOWER_DWORD(READ(c)) == _cont_) &&
225
-					(LOWER_DWORD(READ(c+4)) == _ent__) &&
226
-					(LOWER_DWORD(READ(c+8)) == _type_)
227
-				) {
228
-					/* Content-Type HF found */
229
-					c += content_type_len;
230
-					while ((c < buf_end) &&
231
-						((*c == ' ') || (*c == '\t'))
232
-					)
233
-						c++;
234
-
235
-					if (c + 1 /* : */ >= buf_end)
236
-						return NULL;
237
-
238
-					if (*c != ':')
239
-						/* not realy a Content-Type HF */
240
-						goto next_hf;
241
-					c++;
242
-
243
-					/* search the end of the header body,
244
-					decode_mime_type() needs it */
245
-					c2 = c;
246
-					while (((c2 < buf_end) && (*c2 != '\n')) ||
247
-						((c2+1 < buf_end) && (*c2 == '\n') &&
248
-							((*(c2+1) == ' ') || (*(c2+1) == '\t')))
249
-					)
250
-						c2++;
251
-
252
-					if (c2 >= buf_end)
253
-						return NULL;
254
-					if (*(c2-1) == '\r') c2--;
255
-
256
-					if (!decode_mime_type(c, c2 , &umime)) {
257
-						ERR("failed to decode the mime type\n");
258
-						return NULL;
259
-					}
260
-
261
-					/* c2 points to the CRLF at the end of the line,
262
-					move the pointer to the beginning of the next line */
263
-					c = c2;
264
-					if ((c < buf_end) && (*c == '\r')) c++;
265
-					if ((c < buf_end) && (*c == '\n')) c++;
266
-
267
-					if (umime != ((type<<16)|subtype)) {
268
-						/* this is not the part we are looking for */
269
-						goto next_part;
270
-					}
271
-
272
-					/* the requested type/subtype is found! */
273
-					return get_multipart_body(c,
274
-							buf_end,
275
-							&boundary,
276
-							len);
277
-				}
278
-next_hf:
279
-				/* go to the next line */
280
-				while ((c < buf_end) && (*c != '\n')) c++;
281
-				c++;
282
-			}
283
-			/* CRLF delimeter reached,
284
-			no Content-Type HF was found */
285
-		}
286
-	}
287
-	return NULL;
288
-}
289
-
290
-
291
-/**
292
- * trim_leading_hts
293
- *
294
- * trim leading all spaces ' ' and horizontal tabs '\t' characters.
295
- *   - buffer, pointer to the beginning of the buffer.
296
- *   - end_buffer, pointer to the end of the buffer.
297
- * returns
298
- *   - pointer to the first non-match character if success.
299
- *   - pointer to NULL if the end_buffer is reached.
300
- */
301
-char *trim_leading_hts (char *buffer, char *end_buffer)
302
-{
303
-	char *cpy_buffer = buffer;
304
-	while ((cpy_buffer < end_buffer) &&
305
-			((*cpy_buffer == ' ') || (*cpy_buffer == '\t'))) {
306
-		cpy_buffer++;
307
-	}
308
-
309
-	return ((cpy_buffer < end_buffer) ? cpy_buffer : NULL);
310
-}
311
-
312
-
313
-/**
314
- * trim_leading_e_r
315
- *
316
- * trim leading characters until get a '\r'.
317
- *   - buffer, pointer to the beginning of the buffer.
318
- *   - end_buffer, pointer to the end of the buffer.
319
- *
320
- * returns
321
- *   - pointer to the first '\r' character if success.
322
- *   - pointer to NULL if the end_buffer is reached.
323
- */
324
-char *trim_leading_e_r (char *buffer, char *end_buffer)
325
-{
326
-	char *cpy_buffer = buffer;
327
-	while ((cpy_buffer < end_buffer) && (*cpy_buffer != '\r')) {
328
-		cpy_buffer++;
329
-	}
330
-	return ((cpy_buffer < end_buffer) ? cpy_buffer : NULL);
331
-}
332
-
333
-
334
-/**
335
- * part_multipart_headers_cmp
336
- * trim leading characters until get a '\r'.
337
- * receives
338
- *   - buffer, pointer to the beginning of the headers in a part of the multipart body.
339
- *   - end_buffer, pointer to the end of the headers in the multipart body.
340
- *   - content type/ content subtype.
341
- *         if (type == 0 / subtype == 0): Content-Type: disabled in the search.
342
- *   - content id.
343
- *         if (id == NULL): Content-ID: disabled in the search.
344
- *   - content length.
345
- *         if (length == NULL) Content-Length: disabled in the search.
346
- *
347
- * returns
348
- *   - true, if the part of the multipart body has :
349
- *            -- Content-Type   that matches content_type / content_subtype. (if Content-Type enabled) &&
350
- *            -- Content-ID     that matches content_id. (if Content-ID enabled) &&
351
- *            -- Content-Length that matches content_length. (if Content-Length enabled)
352
- *   - false, if any of them doesnt match.
353
- */
354
-int part_multipart_headers_cmp (char *buffer,
355
-				char *end_buffer,
356
-				unsigned short content_type,
357
-				unsigned short content_subtype,
358
-				char *content_id,
359
-				char *content_length)
360
-{
361
-	int error = 0;
362
-	char *error_msg = NULL;
363
-
364
-	char *cpy_c = NULL;
365
-	char *cpy_d = NULL;
366
-
367
-	char *value_ini = NULL;
368
-	char *value_fin = NULL;
369
-	unsigned int umime;
370
-
371
-	int found = 0;
372
-	int found_content_type   = 0;
373
-	int found_content_id     = 0;
374
-	int found_content_length = 0;
375
-
376
-	if ((buffer == NULL) || (end_buffer == NULL)) {
377
-		error = -1;
378
-		error_msg = "buffer and/or end_buffer are NULL";
379
-	} else {
380
-		cpy_c = buffer;
381
-		cpy_d = end_buffer;
382
-
383
-		if ((content_type == 0) && (content_subtype == 0)) {
384
-			found_content_type   = 1;
385
-		}
386
-		if (content_id == NULL) {
387
-			found_content_id = 1;
388
-		}
389
-		if (content_length == NULL) {
390
-			found_content_length = 1;
391
-		}
392
-
393
-		found = found_content_type * found_content_id * found_content_length;
394
-		while ((!found) && (!error) && (cpy_c < cpy_d)) {
395
-			if ((cpy_c + 8) < cpy_d) {
396
-				if ( (LOWER_DWORD(READ(cpy_c)) == _cont_)
397
-						&& (LOWER_DWORD(READ(cpy_c + 4)) == _ent__) ) {
398
-					cpy_c += 8;
399
-					if ( (!found_content_type)
400
-							&& ((cpy_c + 5) < cpy_d)
401
-							&& ((*(cpy_c + 0) == 't') || (*(cpy_c + 0) == 'T'))
402
-							&& ((*(cpy_c + 1) == 'y') || (*(cpy_c + 1) == 'Y'))
403
-							&& ((*(cpy_c + 2) == 'p') || (*(cpy_c + 2) == 'P'))
404
-							&& ((*(cpy_c + 3) == 'e') || (*(cpy_c + 3) == 'E'))
405
-							&& (*(cpy_c + 4) == ':') ) {
406
-						cpy_c += 5;
407
-						/* value_ has the content of the header */
408
-						value_ini = trim_leading_hts(cpy_c, cpy_d);
409
-						value_fin = trim_leading_e_r(cpy_c, cpy_d);
410
-						if ((value_ini != NULL) && (value_fin != NULL)) {
411
-							cpy_c = value_fin;
412
-							if (decode_mime_type(value_ini, value_fin, &umime)) {
413
-								if (umime == ((content_type<<16)|content_subtype)) {
414
-									found_content_type = 1;
415
-								} else {
416
-									error = -2;
417
-									error_msg = "MIME types mismatch";
418
-								}
419
-							} else {
420
-								error = -3;
421
-								error_msg = "Failed to decode MIME type";
422
-							}
423
-						} else {
424
-							error = -4;
425
-							error_msg = "Failed to perform trim_leading_hts || trim_leading_e_r";
426
-						}
427
-					} else if( (!found_content_id) && ((cpy_c + 3) < cpy_d)
428
-							&& ((*(cpy_c + 0) == 'i') || (*(cpy_c + 0) == 'I'))
429
-							&& ((*(cpy_c + 1) == 'd') || (*(cpy_c + 1) == 'D'))
430
-							&& (*(cpy_c + 2) == ':') ) {
431
-						cpy_c += 3;
432
-						/* value_ has the content of the header */
433
-						value_ini = trim_leading_hts(cpy_c, cpy_d);
434
-						value_fin = trim_leading_e_r(cpy_c, cpy_d);
435
-						if ((value_ini != NULL) && (value_fin != NULL)) {
436
-							cpy_c = value_fin;
437
-							if (strncmp(content_id, value_ini, value_fin-value_ini) == 0) {
438
-								found_content_id = 1;
439
-							} else {
440
-								error = -5;
441
-								error_msg = "Content-ID mismatch";
442
-							}
443
-						} else {
444
-							error = -6;
445
-							error_msg = "Failed to perform trim_leading_hts || trim_leading_e_r";
446
-						}
447
-					} else if( (!found_content_length) && ((cpy_c + 7) < cpy_d)
448
-							&& ((*(cpy_c + 0) == 'l') || (*(cpy_c + 0) == 'L'))
449
-							&& ((*(cpy_c + 1) == 'e') || (*(cpy_c + 1) == 'E'))
450
-							&& ((*(cpy_c + 2) == 'n') || (*(cpy_c + 2) == 'N'))
451
-							&& ((*(cpy_c + 3) == 'g') || (*(cpy_c + 3) == 'G'))
452
-							&& ((*(cpy_c + 4) == 't') || (*(cpy_c + 4) == 'T'))
453
-							&& ((*(cpy_c + 5) == 'h') || (*(cpy_c + 5) == 'H'))
454
-							&& (*(cpy_c + 6) == ':') ) {
455
-						cpy_c += 7;
456
-						/* value_ has the content of the header */
457
-						value_ini = trim_leading_hts(cpy_c, cpy_d);
458
-						value_fin = trim_leading_e_r(cpy_c, cpy_d);
459
-						if ((value_ini != NULL) && (value_fin != NULL)) {
460
-							cpy_c = value_fin;
461
-							if (strncmp(content_length, value_ini, value_fin-value_ini) == 0) {
462
-								found_content_length = 1;
463
-							} else {
464
-								error = -7;
465
-								error_msg = "Content-Length mismatch";
466
-							}
467
-						} else {
468
-							error = -8;
469
-							error_msg = "Failed to perform trim_leading_hts || trim_leading_e_r";
470
-						}
471
-					} else {
472
-						/* Next characters dont match "Type:" or "ID:" or "Length:" OR
473
-					     * header already parsed (maybe duplicates?) and founded OR
474
-					     * header initially set as disabled and it doesnt need to be treated.
475
-					     * This is NOT an error. */
476
-						;
477
-					}
478
-				} else {
479
-					/* First 8 characters dont match "Content-"
480
-					 * This is NOT an error. */
481
-					;
482
-				}
483
-			} else {
484
-				error = -9;
485
-				error_msg = "We reached the end of the buffer";
486
-			}
487
-			found = found_content_type * found_content_id * found_content_length;
488
-			if ((!found) && (!error)) {
489
-				value_fin = trim_leading_e_r(cpy_c, cpy_d);
490
-				if (value_fin != NULL) {
491
-					cpy_c = value_fin;
492
-					if ((cpy_c + 1) < cpy_d) {
493
-						if ((*cpy_c == '\r') && (*(cpy_c + 1) == '\n')) {
494
-							cpy_c++;
495
-							cpy_c++;
496
-						} else {
497
-							error = -10;
498
-							error_msg = "Each line must end with a \r\n";
499
-						}
500
-					} else {
501
-						error = -11;
502
-						error_msg = "We reached the end of the buffer";
503
-					}
504
-				} else {
505
-					error = -12;
506
-					error_msg = "Failed to perform trim_leading_e_r";
507
-				}
508
-			}
509
-		} /* End main while loop */
510
-	}
511
-
512
-	if (error < 0) {
513
-		LM_ERR("part_multipart_headers_cmp. error. \"%i\". \"%s\".\n", error, error_msg);
514
-		return 0;
515
-	} else {
516
-		return found;
517
-	}
518
-}
519
-
520
-/**
521
- * get_body_part_by_filter
522
- *
523
- * Filters the multipart part from a given SIP message which matches the
524
- * Content-Type && || Content-ID  && || Content-Length
525
- * receives
526
- *   - SIP message
527
- *   - pointer to the beginning of the headers in a part of the multipart body.
528
- *   - pointer to the end of the headers in the multipart body.
529
- *   - content type/ content subtype.
530
- *         if (type == 0 / subtype == 0): Content-Type: disabled in the search.
531
- *   - content id.
532
- *         if (id == NULL): Content-ID: disabled in the search.
533
- *   - content length.
534
- *         if (length == NULL) Content-Length: disabled in the search.
535
- *   - len. Length of the multipart message returned.
536
- *
537
- * returns
538
- *   - pointer to the multipart if success.
539
- *   - NULL, if none of the multiparts match.
540
- */
541
-char *get_body_part_by_filter(struct sip_msg *msg,
542
-		     unsigned short content_type,
543
-		     unsigned short content_subtype,
544
-		     char *content_id,
545
-		     char *content_length,
546
-		     int *len)
547
-{
548
-	int mime;
549
-	char*c, *d, *buf_end;
550
-	str boundary;
551
-
552
-	if ((mime = parse_content_type_hdr(msg)) <= 0)
553
-		return NULL;
554
-
555
-	if ((mime>>16) == TYPE_MULTIPART) {
556
-		/* type is multipart/something, search for type/subtype part */
557
-		if (get_boundary_param(msg, &boundary)) {
558
-			ERR("failed to get boundary parameter\n");
559
-			return NULL;
560
-		}
561
-		if (!(c = get_body(msg)))
562
-			return NULL;
563
-		buf_end = msg->buf+msg->len;
564
-
565
-		while ((c = search_boundary(c, buf_end, &boundary))) {
566
-			/* skip boundary */
567
-			c += 2 + boundary.len;
568
-
569
-			if ((c+2 > buf_end) || ((*c == '-') && (*(c+1) == '-')) )
570
-				/* end boundary, no more body part will follow */
571
-				return NULL;
572
-
573
-			/* go to the next line */
574
-			while ((c < buf_end) && (*c != '\n')) c++;
575
-			c++;
576
-			if (c >= buf_end)
577
-				return NULL;
578
-
579
-			d = get_multipart_body(c, buf_end, &boundary, len);
580
-			if (part_multipart_headers_cmp(c, d, content_type, content_subtype,
581
-						content_id, content_length)) {
582
-				return d;
583
-			}
584
-		}
585
-	}
586
-	return NULL;
587
-}
Browse code

core parser - remove svn ID, remove history, change "ser" => "Kamailio"

Olle E. Johansson authored on 18/01/2015 19:36:18
Showing 1 changed files
... ...
@@ -1,19 +1,14 @@
1 1
 /*
2 2
  * Copyright (C) 2008 iptelorg GmbH
3 3
  *
4
- * This file is part of ser, a free SIP server.
4
+ * This file is part of Kamailio, a free SIP server.
5 5
  *
6
- * ser is free software; you can redistribute it and/or modify
6
+ * Kamailio is free software; you can redistribute it and/or modify
7 7
  * it under the terms of the GNU General Public License as published by
8 8
  * the Free Software Foundation; either version 2 of the License, or
9 9
  * (at your option) any later version
10 10
  *
11
- * For a license to use the ser software under conditions
12
- * other than those described here, or to purchase support for this
13
- * software, please contact iptel.org by e-mail at the following addresses:
14
- *    info@iptel.org
15
- *
16
- * ser is distributed in the hope that it will be useful,
11
+ * Kamailio is distributed in the hope that it will be useful,
17 12
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 13
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 14
  * GNU General Public License for more details.
... ...
@@ -22,9 +17,6 @@
22 17
  * along with this program; if not, write to the Free Software 
23 18
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24 19
  *
25
- * History:
26
- * --------
27
- *  2008-05-22  Initial version, get_body_part() is introduced (Miklos)
28 20
  */
29 21
 
30 22
 /*! \file
Browse code

all: updated FSF address in GPL text

Anthony Messina authored on 04/07/2014 09:36:37 • Daniel-Constantin Mierla committed on 04/07/2014 09:37:36
Showing 1 changed files
... ...
@@ -20,7 +20,7 @@
20 20
  *
21 21
  * You should have received a copy of the GNU General Public License 
22 22
  * along with this program; if not, write to the Free Software 
23
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
23
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
24 24
  *
25 25
  * History:
26 26
  * --------
Browse code

core: parser - function to proper handling multipart bodies with same content type

- closes FS#170, based on a patch by Luis Martin

Daniel-Constantin Mierla authored on 25/02/2013 10:19:15
Showing 1 changed files
... ...
@@ -294,3 +294,302 @@ next_hf:
294 294
 	}
295 295
 	return NULL;
296 296
 }
297
+
298
+
299
+/**
300
+ * trim_leading_hts
301
+ *
302
+ * trim leading all spaces ' ' and horizontal tabs '\t' characters.
303
+ *   - buffer, pointer to the beginning of the buffer.
304
+ *   - end_buffer, pointer to the end of the buffer.
305
+ * returns
306
+ *   - pointer to the first non-match character if success.
307
+ *   - pointer to NULL if the end_buffer is reached.
308
+ */
309
+char *trim_leading_hts (char *buffer, char *end_buffer)
310
+{
311
+	char *cpy_buffer = buffer;
312
+	while ((cpy_buffer < end_buffer) &&
313
+			((*cpy_buffer == ' ') || (*cpy_buffer == '\t'))) {
314
+		cpy_buffer++;
315
+	}
316
+
317
+	return ((cpy_buffer < end_buffer) ? cpy_buffer : NULL);
318
+}
319
+
320
+
321
+/**
322
+ * trim_leading_e_r
323
+ *
324
+ * trim leading characters until get a '\r'.
325
+ *   - buffer, pointer to the beginning of the buffer.
326
+ *   - end_buffer, pointer to the end of the buffer.
327
+ *
328
+ * returns
329
+ *   - pointer to the first '\r' character if success.
330
+ *   - pointer to NULL if the end_buffer is reached.
331
+ */
332
+char *trim_leading_e_r (char *buffer, char *end_buffer)
333
+{
334
+	char *cpy_buffer = buffer;
335
+	while ((cpy_buffer < end_buffer) && (*cpy_buffer != '\r')) {
336
+		cpy_buffer++;
337
+	}
338
+	return ((cpy_buffer < end_buffer) ? cpy_buffer : NULL);
339
+}
340
+
341
+
342
+/**
343
+ * part_multipart_headers_cmp
344
+ * trim leading characters until get a '\r'.
345
+ * receives
346
+ *   - buffer, pointer to the beginning of the headers in a part of the multipart body.
347
+ *   - end_buffer, pointer to the end of the headers in the multipart body.
348
+ *   - content type/ content subtype.
349
+ *         if (type == 0 / subtype == 0): Content-Type: disabled in the search.
350
+ *   - content id.
351
+ *         if (id == NULL): Content-ID: disabled in the search.
352
+ *   - content length.
353
+ *         if (length == NULL) Content-Length: disabled in the search.
354
+ *
355
+ * returns
356
+ *   - true, if the part of the multipart body has :
357
+ *            -- Content-Type   that matches content_type / content_subtype. (if Content-Type enabled) &&
358
+ *            -- Content-ID     that matches content_id. (if Content-ID enabled) &&
359
+ *            -- Content-Length that matches content_length. (if Content-Length enabled)
360
+ *   - false, if any of them doesnt match.
361
+ */
362
+int part_multipart_headers_cmp (char *buffer,
363
+				char *end_buffer,
364
+				unsigned short content_type,
365
+				unsigned short content_subtype,
366
+				char *content_id,
367
+				char *content_length)
368
+{
369
+	int error = 0;
370
+	char *error_msg = NULL;
371
+
372
+	char *cpy_c = NULL;
373
+	char *cpy_d = NULL;
374
+
375
+	char *value_ini = NULL;
376
+	char *value_fin = NULL;
377
+	unsigned int umime;
378
+
379
+	int found = 0;
380
+	int found_content_type   = 0;
381
+	int found_content_id     = 0;
382
+	int found_content_length = 0;
383
+
384
+	if ((buffer == NULL) || (end_buffer == NULL)) {
385
+		error = -1;
386
+		error_msg = "buffer and/or end_buffer are NULL";
387
+	} else {
388
+		cpy_c = buffer;
389
+		cpy_d = end_buffer;
390
+
391
+		if ((content_type == 0) && (content_subtype == 0)) {
392
+			found_content_type   = 1;
393
+		}
394
+		if (content_id == NULL) {
395
+			found_content_id = 1;
396
+		}
397
+		if (content_length == NULL) {
398
+			found_content_length = 1;
399
+		}
400
+
401
+		found = found_content_type * found_content_id * found_content_length;
402
+		while ((!found) && (!error) && (cpy_c < cpy_d)) {
403
+			if ((cpy_c + 8) < cpy_d) {
404
+				if ( (LOWER_DWORD(READ(cpy_c)) == _cont_)
405
+						&& (LOWER_DWORD(READ(cpy_c + 4)) == _ent__) ) {
406
+					cpy_c += 8;
407
+					if ( (!found_content_type)
408
+							&& ((cpy_c + 5) < cpy_d)
409
+							&& ((*(cpy_c + 0) == 't') || (*(cpy_c + 0) == 'T'))
410
+							&& ((*(cpy_c + 1) == 'y') || (*(cpy_c + 1) == 'Y'))
411
+							&& ((*(cpy_c + 2) == 'p') || (*(cpy_c + 2) == 'P'))
412
+							&& ((*(cpy_c + 3) == 'e') || (*(cpy_c + 3) == 'E'))
413
+							&& (*(cpy_c + 4) == ':') ) {
414
+						cpy_c += 5;
415
+						/* value_ has the content of the header */
416
+						value_ini = trim_leading_hts(cpy_c, cpy_d);
417
+						value_fin = trim_leading_e_r(cpy_c, cpy_d);
418
+						if ((value_ini != NULL) && (value_fin != NULL)) {
419
+							cpy_c = value_fin;
420
+							if (decode_mime_type(value_ini, value_fin, &umime)) {
421
+								if (umime == ((content_type<<16)|content_subtype)) {
422
+									found_content_type = 1;
423
+								} else {
424
+									error = -2;
425
+									error_msg = "MIME types mismatch";
426
+								}
427
+							} else {
428
+								error = -3;
429
+								error_msg = "Failed to decode MIME type";
430
+							}
431
+						} else {
432
+							error = -4;
433
+							error_msg = "Failed to perform trim_leading_hts || trim_leading_e_r";
434
+						}
435
+					} else if( (!found_content_id) && ((cpy_c + 3) < cpy_d)
436
+							&& ((*(cpy_c + 0) == 'i') || (*(cpy_c + 0) == 'I'))
437
+							&& ((*(cpy_c + 1) == 'd') || (*(cpy_c + 1) == 'D'))
438
+							&& (*(cpy_c + 2) == ':') ) {
439
+						cpy_c += 3;
440
+						/* value_ has the content of the header */
441
+						value_ini = trim_leading_hts(cpy_c, cpy_d);
442
+						value_fin = trim_leading_e_r(cpy_c, cpy_d);
443
+						if ((value_ini != NULL) && (value_fin != NULL)) {
444
+							cpy_c = value_fin;
445
+							if (strncmp(content_id, value_ini, value_fin-value_ini) == 0) {
446
+								found_content_id = 1;
447
+							} else {
448
+								error = -5;
449
+								error_msg = "Content-ID mismatch";
450
+							}
451
+						} else {
452
+							error = -6;
453
+							error_msg = "Failed to perform trim_leading_hts || trim_leading_e_r";
454
+						}
455
+					} else if( (!found_content_length) && ((cpy_c + 7) < cpy_d)
456
+							&& ((*(cpy_c + 0) == 'l') || (*(cpy_c + 0) == 'L'))
457
+							&& ((*(cpy_c + 1) == 'e') || (*(cpy_c + 1) == 'E'))
458
+							&& ((*(cpy_c + 2) == 'n') || (*(cpy_c + 2) == 'N'))
459
+							&& ((*(cpy_c + 3) == 'g') || (*(cpy_c + 3) == 'G'))
460
+							&& ((*(cpy_c + 4) == 't') || (*(cpy_c + 4) == 'T'))
461
+							&& ((*(cpy_c + 5) == 'h') || (*(cpy_c + 5) == 'H'))
462
+							&& (*(cpy_c + 6) == ':') ) {
463
+						cpy_c += 7;
464
+						/* value_ has the content of the header */
465
+						value_ini = trim_leading_hts(cpy_c, cpy_d);
466
+						value_fin = trim_leading_e_r(cpy_c, cpy_d);
467
+						if ((value_ini != NULL) && (value_fin != NULL)) {
468
+							cpy_c = value_fin;
469
+							if (strncmp(content_length, value_ini, value_fin-value_ini) == 0) {
470
+								found_content_length = 1;
471
+							} else {
472
+								error = -7;
473
+								error_msg = "Content-Length mismatch";
474
+							}
475
+						} else {
476
+							error = -8;
477
+							error_msg = "Failed to perform trim_leading_hts || trim_leading_e_r";
478
+						}
479
+					} else {
480
+						/* Next characters dont match "Type:" or "ID:" or "Length:" OR
481
+					     * header already parsed (maybe duplicates?) and founded OR
482
+					     * header initially set as disabled and it doesnt need to be treated.
483
+					     * This is NOT an error. */
484
+						;
485
+					}
486
+				} else {
487
+					/* First 8 characters dont match "Content-"
488
+					 * This is NOT an error. */
489
+					;
490
+				}
491
+			} else {
492
+				error = -9;
493
+				error_msg = "We reached the end of the buffer";
494
+			}
495
+			found = found_content_type * found_content_id * found_content_length;
496
+			if ((!found) && (!error)) {
497
+				value_fin = trim_leading_e_r(cpy_c, cpy_d);
498
+				if (value_fin != NULL) {
499
+					cpy_c = value_fin;
500
+					if ((cpy_c + 1) < cpy_d) {
501
+						if ((*cpy_c == '\r') && (*(cpy_c + 1) == '\n')) {
502
+							cpy_c++;
503
+							cpy_c++;
504
+						} else {
505
+							error = -10;
506
+							error_msg = "Each line must end with a \r\n";
507
+						}
508
+					} else {
509
+						error = -11;
510
+						error_msg = "We reached the end of the buffer";
511
+					}
512
+				} else {
513
+					error = -12;
514
+					error_msg = "Failed to perform trim_leading_e_r";
515
+				}
516
+			}
517
+		} /* End main while loop */
518
+	}
519
+
520
+	if (error < 0) {
521
+		LM_ERR("part_multipart_headers_cmp. error. \"%i\". \"%s\".\n", error, error_msg);
522
+		return 0;
523
+	} else {
524
+		return found;
525
+	}
526
+}
527
+
528
+/**
529
+ * get_body_part_by_filter
530
+ *
531
+ * Filters the multipart part from a given SIP message which matches the
532
+ * Content-Type && || Content-ID  && || Content-Length
533
+ * receives
534
+ *   - SIP message
535
+ *   - pointer to the beginning of the headers in a part of the multipart body.
536
+ *   - pointer to the end of the headers in the multipart body.
537
+ *   - content type/ content subtype.
538
+ *         if (type == 0 / subtype == 0): Content-Type: disabled in the search.
539
+ *   - content id.
540
+ *         if (id == NULL): Content-ID: disabled in the search.
541
+ *   - content length.
542
+ *         if (length == NULL) Content-Length: disabled in the search.
543
+ *   - len. Length of the multipart message returned.
544
+ *
545
+ * returns
546
+ *   - pointer to the multipart if success.
547
+ *   - NULL, if none of the multiparts match.
548
+ */
549
+char *get_body_part_by_filter(struct sip_msg *msg,
550
+		     unsigned short content_type,
551
+		     unsigned short content_subtype,
552
+		     char *content_id,
553
+		     char *content_length,
554
+		     int *len)
555
+{
556
+	int mime;
557
+	char*c, *d, *buf_end;
558
+	str boundary;
559
+
560
+	if ((mime = parse_content_type_hdr(msg)) <= 0)
561
+		return NULL;