parse_content.c 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  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. * [email protected]
  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. * History:
  29. * 2003-08-04 parse_content_type_hdr separates type from subtype inside
  30. * the mime type (bogdan)
  31. * 2003-08-04 CPL subtype added (bogdan)
  32. * 2003-08-05 parse_accept_hdr function added (bogdan)
  33. */
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <sys/types.h>
  37. #include <unistd.h>
  38. #include "../mem/mem.h"
  39. #include "../dprint.h"
  40. #include "../str.h"
  41. #include "../ut.h"
  42. #include "parse_content.h"
  43. #define is_mime_char(_c_) \
  44. (isalpha((int)_c_) || (_c_)=='-' || (_c_)=='+')
  45. #define is_char_equal(_c_,_cs_) \
  46. ( (isalpha((int)_c_)?(((_c_)|0x20)==(_cs_)):((_c_)==(_cs_)))==1 )
  47. /*
  48. * Node of the type's tree; this tree contains all the known types;
  49. */
  50. typedef struct type_node_s {
  51. char c; /* char contained by this node */
  52. unsigned char final; /* says what mime type/subtype was detected
  53. * if string ends at this node */
  54. unsigned char nr_sons; /* the number of sub-nodes */
  55. int next; /* the next sibling node */
  56. }type_node_t;
  57. static type_node_t type_tree[] = {
  58. {'t',TYPE_UNKNOWN,1,4},
  59. {'e',TYPE_UNKNOWN,1,-1},
  60. {'x',TYPE_UNKNOWN,1,-1},
  61. {'t',TYPE_TEXT,0,-1},
  62. {'m',TYPE_UNKNOWN,1,11},
  63. {'e',TYPE_UNKNOWN,1,-1},
  64. {'s',TYPE_UNKNOWN,1,-1},
  65. {'s',TYPE_UNKNOWN,1,-1},
  66. {'a',TYPE_UNKNOWN,1,-1},
  67. {'g',TYPE_UNKNOWN,1,-1},
  68. {'e',TYPE_MESSAGE,0,-1},
  69. {'a',TYPE_UNKNOWN,1,-1},
  70. {'p',TYPE_UNKNOWN,1,-1},
  71. {'p',TYPE_UNKNOWN,1,-1},
  72. {'l',TYPE_UNKNOWN,1,-1},
  73. {'i',TYPE_UNKNOWN,1,-1},
  74. {'c',TYPE_UNKNOWN,1,-1},
  75. {'a',TYPE_UNKNOWN,1,-1},
  76. {'t',TYPE_UNKNOWN,1,-1},
  77. {'i',TYPE_UNKNOWN,1,-1},
  78. {'o',TYPE_UNKNOWN,1,-1},
  79. {'n',TYPE_APPLICATION,0,-1}
  80. };
  81. static type_node_t subtype_tree[] = {
  82. {'p',SUBTYPE_UNKNOWN,1,5},
  83. {'l',SUBTYPE_UNKNOWN,1,-1},
  84. {'a',SUBTYPE_UNKNOWN,1,-1},
  85. {'i',SUBTYPE_UNKNOWN,1,-1},
  86. {'n',SUBTYPE_PLAIN,0,-1},
  87. {'c',SUBTYPE_UNKNOWN,1,10},
  88. {'p',SUBTYPE_UNKNOWN,2,-1},
  89. {'i',SUBTYPE_UNKNOWN,1,9},
  90. {'m',SUBTYPE_CPIM,0,-1},
  91. {'l',SUBTYPE_UNKNOWN,1,-1},
  92. {'+',TYPE_UNKNOWN,1,-1},
  93. {'x',TYPE_UNKNOWN,1,-1},
  94. {'m',TYPE_UNKNOWN,1,-1},
  95. {'l',SUBTYPE_CPLXML,0,-1},
  96. {'s',SUBTYPE_UNKNOWN,1,-1},
  97. {'d',SUBTYPE_UNKNOWN,1,-1},
  98. {'p',SUBTYPE_SDP,0,-1},
  99. };
  100. char* parse_content_length( char* buffer, char* end, int* length)
  101. {
  102. int number;
  103. char *p;
  104. int size;
  105. p = buffer;
  106. /* search the begining of the number */
  107. while ( p<end && (*p==' ' || *p=='\t' ||
  108. (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
  109. p++;
  110. if (p==end)
  111. goto error;
  112. /* parse the number */
  113. size = 0;
  114. number = 0;
  115. while (p<end && *p>='0' && *p<='9') {
  116. number = number*10 + (*p)-'0';
  117. size ++;
  118. p++;
  119. }
  120. if (p==end || size==0)
  121. goto error;
  122. /* now we should have only spaces at the end */
  123. while ( p<end && (*p==' ' || *p=='\t' ||
  124. (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
  125. p++;
  126. if (p==end)
  127. goto error;
  128. /* the header ends proper? */
  129. if ( (*(p++)!='\n') && (*(p-1)!='\r' || *(p++)!='\n' ) )
  130. goto error;
  131. *length = number;
  132. return p;
  133. error:
  134. LOG(L_ERR,"ERROR:parse_content_length: parse error near char [%d][%c]\n",
  135. *p,*p);
  136. return 0;
  137. }
  138. char* decode_mime_type(char *start, char *end, unsigned int *mime_type)
  139. {
  140. int node;
  141. char *mark;
  142. char *p;
  143. p = start;
  144. /* search the begining of the type */
  145. while ( p<end && (*p==' ' || *p=='\t' ||
  146. (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
  147. p++;
  148. if (p==end)
  149. goto error;
  150. /* parse the type */
  151. if (*p=='*') {
  152. *mime_type = TYPE_ALL<<16;
  153. p++;
  154. } else {
  155. node = 0;
  156. mark = p;
  157. while (p<end && is_mime_char(*p) ) {
  158. while ( node!=-1 && !is_char_equal(*p,type_tree[node].c) ){
  159. node = type_tree[node].next;
  160. }
  161. if (node!=-1 && type_tree[node].nr_sons)
  162. node++;
  163. p++;
  164. }
  165. if (p==end || mark==p)
  166. goto error;
  167. if (node!=-1)
  168. *mime_type = type_tree[node].final<<16;
  169. else
  170. *mime_type = TYPE_UNKNOWN<<16;
  171. }
  172. /* search the '/' separator */
  173. while ( p<end && (*p==' ' || *p=='\t' ||
  174. (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
  175. p++;
  176. if ( p==end || *(p++)!='/')
  177. goto error;
  178. /* search the begining of the sub-type */
  179. while ( p<end && (*p==' ' || *p=='\t' ||
  180. (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
  181. p++;
  182. if (p==end)
  183. goto error;
  184. /* parse the sub-type */
  185. if (*p=='*') {
  186. *mime_type |= SUBTYPE_ALL;
  187. p++;
  188. } else {
  189. node = 0;
  190. mark = p;
  191. while (p<end && is_mime_char(*p) ) {
  192. while(node!=-1 && !is_char_equal(*p,subtype_tree[node].c) )
  193. node = subtype_tree[node].next;
  194. if (node!=-1 && subtype_tree[node].nr_sons)
  195. node++;
  196. p++;
  197. }
  198. if (p==mark)
  199. goto error;
  200. if (node!=-1)
  201. *mime_type |= subtype_tree[node].final;
  202. else
  203. *mime_type |= SUBTYPE_UNKNOWN;
  204. }
  205. /* now its possible to have some spaces */
  206. while ( p<end && (*p==' ' || *p=='\t' ||
  207. (*p=='\n' && (*(p+1)==' '||*(p+1)=='\t')) ))
  208. p++;
  209. /* if there are params, ignore them!! -> eat everything to
  210. * the end or to the first ',' */
  211. if ( p<end && *p==';' )
  212. for(p++; p<end && *p!=','; p++);
  213. /* is this the correct end? */
  214. if (p!=end && *p!=',' )
  215. goto error;
  216. /* check the format of the decoded mime */
  217. if ((*mime_type)>>16==TYPE_ALL && ((*mime_type)&0x00ff)!=SUBTYPE_ALL) {
  218. LOG(L_ERR,"ERROR:decode_mine_type: invalid mime format found "
  219. " <*/submime> in [%.*s]!!\n", (int)(end-start),start);
  220. return 0;
  221. }
  222. return p;
  223. error:
  224. LOG(L_ERR,"ERROR:decode_mine_type: parse error near in [%.*s] char"
  225. "[%d][%c] offset=%d\n", (int)(end-start),start,*p,*p,(int)(p-start));
  226. return 0;
  227. }
  228. /* returns: > 0 mime found
  229. * = 0 hdr not found
  230. * =-1 error */
  231. int parse_content_type_hdr( struct sip_msg *msg )
  232. {
  233. char *end;
  234. char *ret;
  235. unsigned int mime;
  236. /* is the header already found? */
  237. if ( msg->content_type==0 ) {
  238. /* if not, found it */
  239. if ( parse_headers(msg,HDR_CONTENTTYPE,0)==-1)
  240. goto error;
  241. if ( msg->content_type==0 ) {
  242. DBG("DEBUG:parse_content_type_hdr: missing Content-Type"
  243. "header\n");
  244. return 0;
  245. }
  246. }
  247. /* maybe the header is already parsed! */
  248. if ( msg->content_type->parsed!=0)
  249. return get_content_type(msg);
  250. /* it seams we have to parse it! :-( */
  251. end = msg->content_type->body.s + msg->content_type->body.len;
  252. ret = decode_mime_type(msg->content_type->body.s, end , &mime);
  253. if (ret==0)
  254. goto error;
  255. if (ret!=end) {
  256. LOG(L_ERR,"ERROR:parse_content_type_hdr: CONTENT_TYPE hdr containes "
  257. "more then one mime type :-(!\n");
  258. goto error;
  259. }
  260. if ((mime&0x00ff)==SUBTYPE_ALL || (mime>>16)==TYPE_ALL) {
  261. LOG(L_ERR,"ERROR:parse_content_type_hdr: invalid mime with wildcard "
  262. "'*' in Content-Type hdr!\n");
  263. goto error;
  264. }
  265. msg->content_type->parsed = (void*)(unsigned long)mime;
  266. return mime;
  267. error:
  268. return -1;
  269. }
  270. /* returns: > 0 ok
  271. * = 0 hdr not found
  272. * = -1 error */
  273. int parse_accept_hdr( struct sip_msg *msg )
  274. {
  275. static unsigned int mimes[MAX_MIMES_NR];
  276. int nr_mimes;
  277. unsigned int mime;
  278. char *end;
  279. char *ret;
  280. /* is the header already found? */
  281. if ( msg->accept==0 ) {
  282. /* if not, found it */
  283. if ( parse_headers(msg,HDR_ACCEPT,0)==-1)
  284. goto error;
  285. if ( msg->accept==0 ) {
  286. DBG("DEBUG:parse_accept_hdr: missing Accept header\n");
  287. return 0;
  288. }
  289. }
  290. /* maybe the header is already parsed! */
  291. if ( msg->accept->parsed!=0)
  292. return 1;
  293. /* it seams we have to parse it! :-( */
  294. ret = msg->accept->body.s;
  295. end = ret + msg->accept->body.len;
  296. nr_mimes = 0;
  297. while (1){
  298. ret = decode_mime_type(ret, end , &mime);
  299. if (ret==0)
  300. goto error;
  301. /* a new mime was found -> put it into array */
  302. if (nr_mimes==MAX_MIMES_NR) {
  303. LOG(L_ERR,"ERROR:parse_accept_hdr: Accept hdr contains more than"
  304. " %d mime type -> buffer ovrflow!!\n",MAX_MIMES_NR);
  305. goto error;
  306. }
  307. mimes[nr_mimes++] = mime;
  308. /* is another mime following? */
  309. if (ret==end )
  310. break;
  311. /* parse the mime separator ',' */
  312. if (*ret!=',' || ret+1==end) {
  313. LOG(L_ERR,"ERROR:parse_accept_hdr: parse error between mimes at "
  314. "char <%x> (offset=%d) in <%.*s>!\n",
  315. *ret, (int)(ret-msg->accept->body.s),
  316. msg->accept->body.len, msg->accept->body.s);
  317. goto error;
  318. }
  319. /* skip the ',' */
  320. ret++;
  321. }
  322. /* copy and link the mime buffer into the message */
  323. msg->accept->parsed = (void*)pkg_malloc((nr_mimes+1)*sizeof(int));
  324. if (msg->accept->parsed==0) {
  325. LOG(L_ERR,"ERROR:parse_accept_hdr: no more pkg memory\n");
  326. goto error;
  327. }
  328. memcpy(msg->accept->parsed,mimes,nr_mimes*sizeof(int));
  329. /* make the buffer null terminated */
  330. ((int*)msg->accept->parsed)[nr_mimes] = 0;
  331. return 1;
  332. error:
  333. return -1;
  334. }