⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 osip_message_parse.c

📁 libosip2-3.0.3最新版本
💻 C
📖 第 1 页 / 共 3 页
字号:
/*  The oSIP library implements the Session Initiation Protocol (SIP -rfc3261-)  Copyright (C) 2001,2002,2003,2004,2005,2006,2007 Aymeric MOIZARD jack@atosc.org    This library is free software; you can redistribute it and/or  modify it under the terms of the GNU Lesser General Public  License as published by the Free Software Foundation; either  version 2.1 of the License, or (at your option) any later version.    This library is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU  Lesser General Public License for more details.    You should have received a copy of the GNU Lesser General Public  License along with this library; if not, write to the Free Software  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#include <stdio.h>#include <stdlib.h>#include <osipparser2/osip_port.h>#include <osipparser2/osip_parser.h>#include "parser.h"static void osip_util_replace_all_lws (char *sip_message);static int osip_message_set__header (osip_message_t * sip, const char *hname,                                     const char *hvalue);static int msg_headers_parse (osip_message_t * sip,                              const char *start_of_header, const char **body);static int msg_osip_body_parse (osip_message_t * sip,                                const char *start_of_buf,                                const char **next_body, size_t length);static int__osip_message_startline_parsereq (osip_message_t * dest, const char *buf,                                   const char **headers){  const char *p1;  const char *p2;  char *requesturi;  int i;  dest->sip_method = NULL;  dest->status_code = 0;  dest->reason_phrase = NULL;  *headers = buf;  /* The first token is the method name: */  p2 = strchr (buf, ' ');  if (p2 == NULL)    return -1;  if (*(p2 + 1) == '\0' || *(p2 + 2) == '\0')    return -1;  if (p2 - buf == 0)    {      OSIP_TRACE (osip_trace                  (__FILE__, __LINE__, OSIP_ERROR, NULL,                   "No space allowed here\n"));      return -1;    }  dest->sip_method = (char *) osip_malloc (p2 - buf + 1);  osip_strncpy (dest->sip_method, buf, p2 - buf);  /* The second token is a sip-url or a uri: */  p1 = strchr (p2 + 2, ' ');    /* no space allowed inside sip-url */  if (p1 == NULL)    {      OSIP_TRACE (osip_trace                  (__FILE__, __LINE__, OSIP_ERROR, NULL,                   "Uncompliant request-uri\n"));      osip_free (dest->sip_method);      dest->sip_method = NULL;      return -1;    }  if (p1 - p2 < 2)    {      osip_free (dest->sip_method);      dest->sip_method = NULL;      return -1;    }  requesturi = (char *) osip_malloc (p1 - p2);  osip_clrncpy (requesturi, p2 + 1, (p1 - p2 - 1));  osip_uri_init (&(dest->req_uri));  i = osip_uri_parse (dest->req_uri, requesturi);  osip_free (requesturi);  if (i != 0)    {      osip_free (dest->sip_method);      dest->sip_method = NULL;      osip_uri_free (dest->req_uri);      dest->req_uri = NULL;      return -1;    }  /* find the the version and the beginning of headers */  {    const char *hp = p1;    while ((*hp != '\r') && (*hp != '\n'))      {        if (*hp)          hp++;        else          {            OSIP_TRACE (osip_trace                        (__FILE__, __LINE__, OSIP_ERROR, NULL, "No crlf found\n"));            osip_free (dest->sip_method);            dest->sip_method = NULL;            osip_uri_free (dest->req_uri);            dest->req_uri = NULL;            return -1;          }      }    if (hp - p1 < 2)      {        osip_free (dest->sip_method);        dest->sip_method = NULL;        osip_uri_free (dest->req_uri);        dest->req_uri = NULL;        return -1;      }    dest->sip_version = (char *) osip_malloc (hp - p1);    osip_strncpy (dest->sip_version, p1 + 1, (hp - p1 - 1));    if (0 != osip_strcasecmp (dest->sip_version, "SIP/2.0"))      {        OSIP_TRACE (osip_trace                    (__FILE__, __LINE__, OSIP_ERROR, NULL,                     "Wrong version number\n"));      }    hp++;    if ((*hp) && ('\r' == hp[-1]) && ('\n' == hp[0]))      hp++;    (*headers) = hp;  }  return 0;}static int__osip_message_startline_parseresp (osip_message_t * dest, const char *buf,                                    const char **headers){  const char *statuscode;  const char *reasonphrase;  dest->req_uri = NULL;  dest->sip_method = NULL;  *headers = buf;  statuscode = strchr (buf, ' ');       /* search for first SPACE */  if (statuscode == NULL)    return -1;  dest->sip_version = (char *) osip_malloc (statuscode - (*headers) + 1);  osip_strncpy (dest->sip_version, *headers, statuscode - (*headers));  reasonphrase = strchr (statuscode + 1, ' ');  if (reasonphrase == NULL)    {      osip_free (dest->sip_version);      dest->sip_version = NULL;      return -1;    }  /* dest->status_code = (char *) osip_malloc (reasonphrase - statuscode); */  /* osip_strncpy (dest->status_code, statuscode + 1, reasonphrase - statuscode - 1); */  if (sscanf (statuscode + 1, "%d", &dest->status_code) != 1)    {      /* Non-numeric status code */      return -1;    }  if (dest->status_code == 0)    return -1;  {    const char *hp = reasonphrase;    while ((*hp != '\r') && (*hp != '\n'))      {        if (*hp)          hp++;        else          {            OSIP_TRACE (osip_trace                        (__FILE__, __LINE__, OSIP_ERROR, NULL, "No crlf found\n"));            return -1;          }      }    dest->reason_phrase = (char *) osip_malloc (hp - reasonphrase);    osip_strncpy (dest->reason_phrase, reasonphrase + 1, hp - reasonphrase - 1);    hp++;    if ((*hp) && ('\r' == hp[-1]) && ('\n' == hp[0]))      hp++;    (*headers) = hp;  }  return 0;}static int__osip_message_startline_parse (osip_message_t * dest, const char *buf,                                const char **headers){  if (0 == strncmp ((const char *) buf, (const char *) "SIP/", 4))    return __osip_message_startline_parseresp (dest, buf, headers);  else    return __osip_message_startline_parsereq (dest, buf, headers);}int__osip_find_next_occurence (const char *str, const char *buf,                            const char **index_of_str, const char *end_of_buf){  int i;  *index_of_str = NULL;         /* AMD fix */  if ((NULL == str) || (NULL == buf))    return -1;  /* TODO? we may prefer strcasestr instead of strstr? */  for (i = 0; i < 1000; i++)    {      *index_of_str = strstr (buf, str);      if (NULL == (*index_of_str))        {          /* if '\0' (when binary data is used) is located before the separator,             then we have to continue searching */          const char *ptr = buf + strlen (buf);          if (end_of_buf - ptr > 0)            {              buf = ptr + 1;              continue;            }          return -1;        }      return 0;    }  OSIP_TRACE (osip_trace              (__FILE__, __LINE__, OSIP_BUG, NULL,               "This was probably an infinite loop?\n"));  return -1;}/* This method replace all LWS with SP located before the   initial CRLFCRLF found or the end of the string.*/static voidosip_util_replace_all_lws (char *sip_message){  /* const char *end_of_message; */  char *tmp;  if (sip_message == NULL)    return;  /* end_of_message = sip_message + strlen (sip_message); */  tmp = sip_message;  for (; tmp[0] != '\0'; tmp++)    {      if (('\0' == tmp[0])          || ('\0' == tmp[1]) || ('\0' == tmp[2]) || ('\0' == tmp[3]))        return;      if ((('\r' == tmp[0]) && ('\n' == tmp[1])           && ('\r' == tmp[2]) && ('\n' == tmp[3]))          ||          (('\r' == tmp[0]) && ('\r' == tmp[1]))          || (('\n' == tmp[0]) && ('\n' == tmp[1])))        return;                 /* end of message */      if ((('\r' == tmp[0]) && ('\n' == tmp[1])           && ((' ' == tmp[2]) || ('\t' == tmp[2])))          ||          (('\r' == tmp[0])           && ((' ' == tmp[1]) || ('\t' == tmp[1])))          || (('\n' == tmp[0]) && ((' ' == tmp[1]) || ('\t' == tmp[1]))))        {          /* replace line end and TAB symbols by SP */          tmp[0] = ' ';          tmp[1] = ' ';          tmp = tmp + 2;          /* replace all following TAB symbols */          for (; ('\t' == tmp[0] || ' ' == tmp[0]);)            {              tmp[0] = ' ';              tmp++;            }        }    }}int__osip_find_next_crlf (const char *start_of_header, const char **end_of_header){  const char *soh = start_of_header;  *end_of_header = NULL;        /* AMD fix */  while (('\r' != *soh) && ('\n' != *soh))    {      if (*soh)        soh++;      else        {          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_ERROR, NULL,                       "Final CRLF is missing\n"));          return -1;        }    }  if (('\r' == soh[0]) && ('\n' == soh[1]))    /* case 1: CRLF is the separator       case 2 or 3: CR or LF is the separator */    soh = soh + 1;  /* VERIFY if TMP is the end of header or LWS.            */  /* LWS are extra SP, HT, CR and LF contained in headers. */  if ((' ' == soh[1]) || ('\t' == soh[1]))    {      /* From now on, incoming message that potentially         contains LWS must be processed with         -> void osip_util_replace_all_lws(char *)         This is because the parser methods does not         support detection of LWS inside. */      OSIP_TRACE (osip_trace                  (__FILE__, __LINE__, OSIP_BUG, NULL,                   "Message that contains LWS must be processed with osip_util_replace_all_lws(char *tmp) before being parsed.\n"));      return -1;    }  *end_of_header = soh + 1;  return 0;}int__osip_find_next_crlfcrlf (const char *start_of_part, const char **end_of_part){  const char *start_of_line;  const char *end_of_line;  int i;  start_of_line = start_of_part;  for (;;)    {      i = __osip_find_next_crlf (start_of_line, &end_of_line);      if (i == -1)        {                       /* error case??? no end of mesage found */          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_ERROR, NULL,                       "Final CRLF is missing\n"));          return -1;        }      if ('\0' == end_of_line[0])        {                       /* error case??? no end of message found */          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_ERROR, NULL,                       "Final CRLF is missing\n"));          return -1;      } else if ('\r' == end_of_line[0])        {          if ('\n' == end_of_line[1])            end_of_line++;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -