Browse code

functions for parsing content_type and content_length added.

Bogdan-Andrei Iancu authored on 28/11/2002 16:14:53
Showing 5 changed files
... ...
@@ -59,7 +59,7 @@ void clean_hdr_field(struct hdr_field* hf)
59 59
 			free_cseq(hf->parsed);
60 60
 			break;
61 61
 
62
-                case HDR_AUTHORIZATION:
62
+		case HDR_AUTHORIZATION:
63 63
 		case HDR_PROXYAUTH:
64 64
 			free_credentials((auth_body_t**)(&(hf->parsed)));
65 65
 			break;
... ...
@@ -80,6 +80,10 @@ void clean_hdr_field(struct hdr_field* hf)
80 80
 			free_contact((contact_body_t**)(&(hf->parsed)));
81 81
 			break;
82 82
 
83
+		case HDR_CONTENTLENGTH:
84
+		case HDR_CONTENTTYPE:
85
+			break;
86
+
83 87
 		default:
84 88
 			LOG(L_CRIT, "BUG: clean_hdr_field: unknown header type %d\n",
85 89
 			    hf->type);
... ...
@@ -43,6 +43,7 @@
43 43
 #include "../globals.h"
44 44
 #include "parse_hname2.h"
45 45
 #include "parse_uri.h"
46
+#include "parse_content.h"
46 47
 
47 48
 #ifdef DEBUG_DMALLOC
48 49
 #include <mem/dmalloc.h>
... ...
@@ -64,6 +65,7 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
64 65
 	struct via_body *vb;
65 66
 	struct cseq_body* cseq_b;
66 67
 	struct to_body* to_b;
68
+	int integer;
67 69
 
68 70
 	if ((*buf)=='\n' || (*buf)=='\r'){
69 71
 		/* double crlf or lflf or crcr */
... ...
@@ -139,24 +141,44 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
139 141
 				hdr->name.s, hdr->body.len, to_b->uri.len,to_b->uri.s);
140 142
 			DBG("DEBUG: to body [%.*s]\n",to_b->body.len,to_b->body.s);
141 143
 			break;
144
+		case HDR_CONTENTLENGTH:
145
+			hdr->body.s=tmp;
146
+			tmp=parse_content_length(tmp,end, &integer);
147
+			if (tmp==0){
148
+				LOG(L_ERR, "ERROR:get_hdr_field: bad content_length header\n");
149
+				goto error;
150
+			}
151
+			hdr->parsed=(void*)integer;
152
+			hdr->body.len=tmp-hdr->body.s;
153
+			DBG("DEBUG: get_hdr_body : content_length=%d\n",(int)hdr->parsed);
154
+			break;
155
+		case HDR_CONTENTTYPE:
156
+			hdr->body.s=tmp;
157
+			tmp=parse_content_type(tmp,end, &integer);
158
+			if (tmp==0){
159
+				LOG(L_ERR, "ERROR:get_hdr_field: bad content_type header\n");
160
+				goto error;
161
+			}
162
+			hdr->parsed=(void*)integer;
163
+			hdr->body.len=tmp-hdr->body.s;
164
+			DBG("DEBUG: get_hdr_body : content_type=%d\n",(int)hdr->parsed);
165
+			break;
142 166
 		case HDR_FROM:
143 167
 		case HDR_CALLID:
144 168
 		case HDR_CONTACT:
145 169
 		case HDR_ROUTE:
146 170
 		case HDR_RECORDROUTE:
147 171
 		case HDR_MAXFORWARDS:
148
-		case HDR_CONTENTTYPE:
149
-		case HDR_CONTENTLENGTH:
150
-	        case HDR_AUTHORIZATION:
151
-	        case HDR_EXPIRES:
152
-	        case HDR_PROXYAUTH:
153
-	        case HDR_WWWAUTH:
154
-	        case HDR_SUPPORTED:
155
-	        case HDR_REQUIRE:
156
-	        case HDR_PROXYREQUIRE:
157
-	        case HDR_UNSUPPORTED:
158
-	        case HDR_ALLOW:
159
-	        case HDR_EVENT:
172
+		case HDR_AUTHORIZATION:
173
+		case HDR_EXPIRES:
174
+		case HDR_PROXYAUTH:
175
+		case HDR_WWWAUTH:
176
+		case HDR_SUPPORTED:
177
+		case HDR_REQUIRE:
178
+		case HDR_PROXYREQUIRE:
179
+		case HDR_UNSUPPORTED:
180
+		case HDR_ALLOW:
181
+		case HDR_EVENT:
160 182
 		case HDR_OTHER:
161 183
 			/* just skip over it */
162 184
 			hdr->body.s=tmp;
... ...
@@ -286,39 +308,39 @@ int parse_headers(struct sip_msg* msg, int flags, int next)
286 308
 				if (msg->content_length==0) msg->content_length = hf;
287 309
 				msg->parsed_flag|=HDR_CONTENTLENGTH;
288 310
 				break;
289
-		        case HDR_AUTHORIZATION:
290
-			        if (msg->authorization==0) msg->authorization = hf;
311
+			case HDR_AUTHORIZATION:
312
+				if (msg->authorization==0) msg->authorization = hf;
291 313
 				msg->parsed_flag|=HDR_AUTHORIZATION;
292 314
 				break;
293
-        		case HDR_EXPIRES:
315
+			case HDR_EXPIRES:
294 316
 				if (msg->expires==0) msg->expires = hf;
295 317
 				msg->parsed_flag|=HDR_EXPIRES;
296 318
 				break;
297
-		        case HDR_PROXYAUTH:
319
+			case HDR_PROXYAUTH:
298 320
 				if (msg->proxy_auth==0) msg->proxy_auth = hf;
299 321
 				msg->parsed_flag|=HDR_PROXYAUTH;
300 322
 				break;
301
-		        case HDR_WWWAUTH:
323
+			case HDR_WWWAUTH:
302 324
 				if (msg->www_auth==0) msg->www_auth = hf;
303 325
 				msg->parsed_flag|=HDR_WWWAUTH;
304 326
 				break;
305
-		        case HDR_SUPPORTED:
327
+			case HDR_SUPPORTED:
306 328
 				if (msg->supported==0) msg->supported = hf;
307 329
 				msg->parsed_flag|=HDR_SUPPORTED;
308 330
 				break;
309
-		        case HDR_REQUIRE:
331
+			case HDR_REQUIRE:
310 332
 				if (msg->require==0) msg->require = hf;
311 333
 				msg->parsed_flag|=HDR_REQUIRE;
312 334
 				break;
313
-		        case HDR_PROXYREQUIRE:
335
+			case HDR_PROXYREQUIRE:
314 336
 				if (msg->proxy_require==0) msg->proxy_require = hf;
315 337
 				msg->parsed_flag|=HDR_PROXYREQUIRE;
316 338
 				break;
317
-		        case HDR_UNSUPPORTED:
339
+			case HDR_UNSUPPORTED:
318 340
 				if (msg->unsupported==0) msg->unsupported=hf;
319 341
 				msg->parsed_flag|=HDR_UNSUPPORTED;
320 342
 				break;
321
-		        case HDR_ALLOW:
343
+			case HDR_ALLOW:
322 344
 				if (msg->allow==0) msg->allow = hf;
323 345
 				msg->parsed_flag|=HDR_ALLOW;
324 346
 				break;
... ...
@@ -208,4 +208,24 @@ inline static int char_msg_val( struct sip_msg *msg, char *cv )
208 208
 	return 1;
209 209
 }
210 210
 
211
+
212
+/* returns a pointer to the begining of the msg's body
213
+ */
214
+inline static char* get_body(struct sip_msg *msg)
215
+{
216
+	int offset;
217
+
218
+	if ( parse_headers(msg,HDR_EOH, 0)==-1 )
219
+		return 0;
220
+
221
+	if ( strncmp(CRLF,msg->unparsed,CRLF_LEN)==0 )
222
+		offset = CRLF_LEN;
223
+	else if (*(msg->unparsed)=='\n' || *(msg->unparsed)=='\r' )
224
+		offset = 1;
225
+	else
226
+		return 0;
227
+
228
+	return msg->unparsed + offset;
229
+}
230
+
211 231
 #endif
212 232
new file mode 100644
... ...
@@ -0,0 +1,194 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ *
5
+ * Copyright (C) 2001-2003 Fhg Fokus
6
+ *
7
+ * This file is part of ser, a free SIP server.
8
+ *
9
+ * ser is free software; you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation; either version 2 of the License, or
12
+ * (at your option) any later version
13
+ *
14
+ * For a license to use the ser software under conditions
15
+ * other than those described here, or to purchase support for this
16
+ * software, please contact iptel.org by e-mail at the following addresses:
17
+ *    info@iptel.org
18
+ *
19
+ * ser is distributed in the hope that it will be useful,
20
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
+ * GNU General Public License for more details.
23
+ *
24
+ * You should have received a copy of the GNU General Public License 
25
+ * along with this program; if not, write to the Free Software 
26
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
+ */
28
+
29
+
30
+#include <stdio.h>
31
+#include <stdlib.h>
32
+#include <sys/types.h>
33
+#include <unistd.h>
34
+#include "../dprint.h"
35
+#include "../str.h"
36
+#include "../ut.h"
37
+#include "parse_content.h"
38
+
39
+
40
+typedef struct type_node_s {
41
+	char c;
42
+	unsigned char final;
43
+	unsigned char nr_sons;
44
+	int next;
45
+}type_node_t;
46
+
47
+
48
+char* parse_content_length( char* buffer, char* end, int* length)
49
+{
50
+	int number;
51
+	char *p;
52
+	int  size;
53
+
54
+	p = buffer;
55
+	/* search the begining of the number */
56
+	while ( p<end && (*p==' ' || *p=='\t' ||
57
+	(*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
58
+		p++;
59
+	if (p==end)
60
+		goto error;
61
+	/* parse the number */
62
+	size = 0;
63
+	number = 0;
64
+	while (p<end && *p>='0' && *p<='9') {
65
+		number = number*10 + (*p)-'0';
66
+		size ++;
67
+		p++;
68
+	}
69
+	if (p==end || size==0)
70
+		goto error;
71
+	/* now we should have only spaces at the end */
72
+	while ( p<end && (*p==' ' || *p=='\t' ||
73
+	(*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
74
+		p++;
75
+	if (p==end)
76
+		goto error;
77
+	/* the header ends proper? */
78
+	if ( (*(p++)!='\n') && (*(p-1)!='\r' || *(p++)!='\n' ) )
79
+		goto error;
80
+
81
+	*length = number;
82
+	return p;
83
+error:
84
+	LOG(L_ERR,"ERROR:parse_content_length: parse error near char [%d][%c]\n",
85
+		*p,*p);
86
+	return 0;
87
+}
88
+
89
+
90
+
91
+
92
+char* parse_content_type( char* buffer, char* end, int* type)
93
+{
94
+	static type_node_t type_tree[] = {
95
+		{'t',-1,1,4}, {'e',-1,1,-1}, {'x',-1,1,-1}, {'t',0,0,-1},
96
+		{'m',-1,1,11}, {'e',-1,1,-1}, {'s',-1,1,-1}, {'s',-1,1,-1},
97
+			{'a',-1,1,-1},{'g',-1,1,-1}, {'e',5,0,-1},
98
+		{'a',-1,1,-1}, {'p',-1,1,-1}, {'p',-1,1,-1}, {'l',-1,1,-1},
99
+			{'i',-1,1,-1},{'c',-1,1,-1},{'a',-1,1,-1},{'t',-1,1,-1},
100
+			{'i',-1,1,-1},{'o',-1,1,-1},{'n',9,0,-1}
101
+	};
102
+	static type_node_t subtype_tree[] = {
103
+		{'p',0,1,5}, {'l',0,1,-1}, {'a',0,1,-1}, {'i',0,1,-1},
104
+			{'n',CONTENT_TYPE_TEXT_PLAIN,0,-1},
105
+		{'c',0,1,9}, {'p',0,1,-1}, {'i',0,1,-1},
106
+			{'m',CONTENT_TYPE_MESSAGE_CPIM,0,-1},
107
+		{'s',0,1,-1}, {'d',0,1,-1},
108
+			{'p',CONTENT_TYPE_APPLICATION_SDP,0,-1},
109
+	};
110
+	int node;
111
+	int mime;
112
+	char *p;
113
+
114
+	p = buffer;
115
+	mime = CONTENT_TYPE_UNKNOWN;
116
+
117
+	/* search the begining of the type */
118
+	while ( p<end && (*p==' ' || *p=='\t' ||
119
+	(*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
120
+		p++;
121
+	if (p==end)
122
+		goto error;
123
+
124
+	/* parse the type */
125
+	node = 0;
126
+	while (p<end && ((*p>='a' && *p<='z') || (*p>='A' && *p<='Z')) ) {
127
+		while ( node!=-1 && type_tree[node].c!=*p && type_tree[node].c+32!=*p){
128
+			node = type_tree[node].next;
129
+		}
130
+		if (node!=-1 && type_tree[node].nr_sons)
131
+			node++;
132
+		p++;
133
+	}
134
+	if (p==end || node==0)
135
+		goto error;
136
+	if (node!=-1)
137
+		node = type_tree[node].final;
138
+
139
+	/* search the '/' separator */
140
+	while ( p<end && (*p==' ' || *p=='\t' ||
141
+	(*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
142
+		p++;
143
+	if ( p==end || *(p++)!='/')
144
+		goto error;
145
+
146
+	/* search the begining of the sub-type */
147
+	while ( p<end && (*p==' ' || *p=='\t' ||
148
+	(*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
149
+		p++;
150
+	if (p==end)
151
+		goto error;
152
+
153
+	/* parse the sub-type */
154
+	while (p<end && ((*p>='a' && *p<='z') || (*p>='A' && *p<='Z')) ) {
155
+		while(node!=-1&&subtype_tree[node].c!=*p&&subtype_tree[node].c+32!=*p)
156
+			node = subtype_tree[node].next;
157
+		if (node!=-1 && subtype_tree[node].nr_sons)
158
+			node++;
159
+		p++;
160
+	}
161
+	if (p==end || node==0)
162
+		goto error;
163
+	if (node!=-1)
164
+		mime = subtype_tree[node].final;
165
+
166
+	/* now its possible to have some spaces */
167
+	while ( p<end && (*p==' ' || *p=='\t' ||
168
+	(*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
169
+		p++;
170
+	if (p==end)
171
+		goto error;
172
+
173
+	/* if there are params, eat everything to the end */
174
+	if (*p==';') {
175
+		while ( p<end && (*p!='\n' || (*(p+1)==' '||*(p+1)=='\t')) )
176
+			p++;
177
+		if (p==end)
178
+			goto error;
179
+	}
180
+
181
+	/* the header ends proper? */
182
+	if ( (*(p++)!='\n') && (*(p-1)!='\r' || *(p++)!='\n' ) )
183
+		goto error;
184
+
185
+	*type = mime;
186
+	return p;
187
+error:
188
+	LOG(L_ERR,"ERROR:parse_content_length: parse error near char [%d][%c]\n",
189
+		*p,*p);
190
+	return 0;
191
+}
192
+
193
+
194
+
0 195
new file mode 100644
... ...
@@ -0,0 +1,41 @@
1
+/*
2
+ * $Id$
3
+ *
4
+ *
5
+ * Copyright (C) 2001-2003 Fhg Fokus
6
+ *
7
+ * This file is part of ser, a free SIP server.
8
+ *
9
+ * ser is free software; you can redistribute it and/or modify
10
+ * it under the terms of the GNU General Public License as published by
11
+ * the Free Software Foundation; either version 2 of the License, or
12
+ * (at your option) any later version
13
+ *
14
+ * For a license to use the ser software under conditions
15
+ * other than those described here, or to purchase support for this
16
+ * software, please contact iptel.org by e-mail at the following addresses:
17
+ *    info@iptel.org
18
+ *
19
+ * ser is distributed in the hope that it will be useful,
20
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
21
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
+ * GNU General Public License for more details.
23
+ *
24
+ * You should have received a copy of the GNU General Public License 
25
+ * along with this program; if not, write to the Free Software 
26
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27
+ */
28
+
29
+#ifndef _PARSE_CONTENT_H
30
+#define _PARSE_CONTENT_H
31
+
32
+#define CONTENT_TYPE_UNKNOWN         0
33
+#define CONTENT_TYPE_TEXT_PLAIN      1
34
+#define CONTENT_TYPE_MESSAGE_CPIM    2
35
+#define CONTENT_TYPE_APPLICATION_SDP 3
36
+
37
+
38
+char* parse_content_type( char* buffer, char* end, int* type);
39
+char* parse_content_length( char* buffer, char* end, int* len);
40
+
41
+#endif