Browse code

Content-Type header's body is no longer parse in get_hdr_field(). For this there is a new function available - parse_content_type_hdr(struct sip_msg*). Content-Length's body parser is still in parse in get_hdr_field(). This parser is very fast and it does not affect the overall perfs.i

Bogdan-Andrei Iancu authored on 24/01/2003 16:44:43
Showing 4 changed files
... ...
@@ -153,16 +153,6 @@ char* get_hdr_field(char* buf, char* end, struct hdr_field* hdr)
153 153
 			DBG("DEBUG: get_hdr_body : content_length=%d\n",(int)hdr->parsed);
154 154
 			break;
155 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;
166 156
 		case HDR_FROM:
167 157
 		case HDR_CALLID:
168 158
 		case HDR_CONTACT:
... ...
@@ -129,7 +129,7 @@ struct sip_msg {
129 129
 	
130 130
 	str new_uri; /* changed first line uri*/
131 131
 
132
-        str dst_uri; /* Destination URI, must be forwarded to this URI if len != 0 */
132
+	str dst_uri; /* Destination URI, must be forwarded to this URI if len != 0 */
133 133
 
134 134
 	int parsed_uri_ok; /* 1 if parsed_uri is valid, 0 if not */
135 135
 	struct sip_uri parsed_uri; /* speed-up > keep here the parsed uri*/
... ...
@@ -36,15 +36,23 @@
36 36
 #include "../ut.h"
37 37
 #include "parse_content.h"
38 38
 
39
-
39
+/*
40
+ * Node of the type's tree; this tree contains all the known types;
41
+ */
40 42
 typedef struct type_node_s {
41
-	char c;
42
-	unsigned char final;
43
-	unsigned char nr_sons;
44
-	int next;
43
+	char c;                      /* char contained by this node */
44
+	unsigned char final;         /* says what to be done if the mached string
45
+	                              * ends at this node: -1-> dead end (unknown
46
+	                              * type) or the index of the sub-type that
47
+	                              * follows (for types) or the  final type (for
48
+	                              * sub-types)*/
49
+	unsigned char nr_sons;       /* the number of sub-nodes */
50
+	int next;                    /* the next sibling node */
45 51
 }type_node_t;
46 52
 
47 53
 
54
+
55
+
48 56
 char* parse_content_length( char* buffer, char* end, int* length)
49 57
 {
50 58
 	int number;
... ...
@@ -89,7 +97,8 @@ error:
89 97
 
90 98
 
91 99
 
92
-char* parse_content_type( char* buffer, char* end, int* type)
100
+
101
+int parse_content_type_hdr( struct sip_msg *msg )
93 102
 {
94 103
 	static type_node_t type_tree[] = {
95 104
 		{'t',-1,1,4}, {'e',-1,1,-1}, {'x',-1,1,-1}, {'t',0,0,-1},
... ...
@@ -109,9 +118,28 @@ char* parse_content_type( char* buffer, char* end, int* type)
109 118
 	};
110 119
 	int node;
111 120
 	int mime;
112
-	char *p;
121
+	char *mark;
122
+	char *p, *end;
123
+
124
+	/* is the header already found? */
125
+	if ( msg->content_type==0 ) {
126
+		/* if not, found it */
127
+		if ( parse_headers(msg,HDR_CONTENTTYPE,0)==-1)
128
+			return -1;
129
+		if ( msg->content_type==0 ) {
130
+			LOG(L_ERR,"ERROR:parse_content_type_header: missing Content-Type"
131
+					"header\n");
132
+			return -1;
133
+		}
134
+	}
113 135
 
114
-	p = buffer;
136
+	/* maybe the header is already parsed! */
137
+	if ( get_content_type(msg)!=CONTENT_TYPE_UNPARSED)
138
+		return get_content_type(msg);
139
+
140
+	/* it seams we have to parse it! :-( */
141
+	p = msg->content_type->body.s;
142
+	end = p + msg->content_type->body.len;
115 143
 	mime = CONTENT_TYPE_UNKNOWN;
116 144
 
117 145
 	/* search the begining of the type */
... ...
@@ -123,6 +151,7 @@ char* parse_content_type( char* buffer, char* end, int* type)
123 151
 
124 152
 	/* parse the type */
125 153
 	node = 0;
154
+	mark = p;
126 155
 	while (p<end && ((*p>='a' && *p<='z') || (*p>='A' && *p<='Z')) ) {
127 156
 		while ( node!=-1 && type_tree[node].c!=*p && type_tree[node].c+32!=*p){
128 157
 			node = type_tree[node].next;
... ...
@@ -131,7 +160,7 @@ char* parse_content_type( char* buffer, char* end, int* type)
131 160
 			node++;
132 161
 		p++;
133 162
 	}
134
-	if (p==end || node==0)
163
+	if (p==end || mark==p)
135 164
 		goto error;
136 165
 	if (node!=-1)
137 166
 		node = type_tree[node].final;
... ...
@@ -151,6 +180,7 @@ char* parse_content_type( char* buffer, char* end, int* type)
151 180
 		goto error;
152 181
 
153 182
 	/* parse the sub-type */
183
+	mark = p;
154 184
 	while (p<end && ((*p>='a' && *p<='z') || (*p>='A' && *p<='Z')) ) {
155 185
 		while(node!=-1&&subtype_tree[node].c!=*p&&subtype_tree[node].c+32!=*p)
156 186
 			node = subtype_tree[node].next;
... ...
@@ -158,7 +188,7 @@ char* parse_content_type( char* buffer, char* end, int* type)
158 188
 			node++;
159 189
 		p++;
160 190
 	}
161
-	if (p==end || node==0)
191
+	if (p==mark)
162 192
 		goto error;
163 193
 	if (node!=-1)
164 194
 		mime = subtype_tree[node].final;
... ...
@@ -167,27 +197,18 @@ char* parse_content_type( char* buffer, char* end, int* type)
167 197
 	while ( p<end && (*p==' ' || *p=='\t' ||
168 198
 	(*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
169 199
 		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 200
 
181
-	/* the header ends proper? */
182
-	if ( (*(p++)!='\n') && (*(p-1)!='\r' || *(p++)!='\n' ) )
201
+	/* is this the end? if there are params, ignore them!! */
202
+	if ( *p!=';' && p!=end )
183 203
 		goto error;
184 204
 
185
-	*type = mime;
186
-	return p;
205
+	mime = ((mime==-1)?CONTENT_TYPE_UNKNOWN:mime);
206
+	(int)(msg->content_type->parsed) = mime;
207
+	return mime;
187 208
 error:
188
-	LOG(L_ERR,"ERROR:parse_content_type: parse error near char [%d][%c]\n",
189
-		*p,*p);
190
-	return 0;
209
+	LOG(L_ERR,"ERROR:parse_content_type: parse error near char [%d][%c] "
210
+		"offset=%d\n",*p,*p,p-msg->content_type->body.s);
211
+	return -1;
191 212
 }
192 213
 
193 214
 
... ...
@@ -29,13 +29,46 @@
29 29
 #ifndef _PARSE_CONTENT_H
30 30
 #define _PARSE_CONTENT_H
31 31
 
32
-#define CONTENT_TYPE_UNKNOWN         0
32
+#include "msg_parser.h"
33
+
34
+/*
35
+ * Types for Content-Type header that are recognize
36
+ */
37
+#define CONTENT_TYPE_UNPARSED        0
33 38
 #define CONTENT_TYPE_TEXT_PLAIN      1
34 39
 #define CONTENT_TYPE_MESSAGE_CPIM    2
35 40
 #define CONTENT_TYPE_APPLICATION_SDP 3
41
+#define CONTENT_TYPE_UNKNOWN         0x7fff
42
+
43
+
44
+
45
+/*
46
+ * returns the content-length value of a sip_msg as an integer
47
+ */
48
+#define get_content_length(_msg_)   ((int)((_msg_)->content_length->parsed))
36 49
 
37 50
 
38
-char* parse_content_type( char* buffer, char* end, int* type);
51
+/*
52
+ * returns the content-type value of a sip_msg as an integer
53
+ */
54
+#define get_content_type(_msg_)   ((int)((_msg_)->content_type->parsed))
55
+
56
+
57
+
58
+/*
59
+ * parse the the body of the Content-Type header. It's value is also converted
60
+ * as int.
61
+ * Returns:   n (n>0)  : the found type
62
+ *           -1        : error (parse error or hdr not found)
63
+ */
64
+int parse_content_type_hdr( struct sip_msg *msg);
65
+
66
+
67
+/*
68
+ *  parse the body of a Content_-Length header. Also tryes to recognize the
69
+ *  type specified by this header (see th above defines).
70
+ *  Returns the first chr after the end of the header.
71
+ */
39 72
 char* parse_content_length( char* buffer, char* end, int* len);
40 73
 
41 74
 #endif