📄 osip_message_parse.c
字号:
if (i == -1) return -1; return 0; } } } return -1; /* if comma is NULL, we should have already return 0 */}/* set all headers */intmsg_headers_parse (osip_message_t * sip, const char *start_of_header, const char **body){ const char *colon_index; /* index of ':' */ char *hname; char *hvalue; const char *end_of_header; int i; for (;;) { i = __osip_find_next_crlf (start_of_header, &end_of_header); if (i == -1) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "End of header Not found\n")); return -1; /* this is an error case! */ } if (end_of_header[0] == '\0') { /* final CRLF is missing */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "SIP message does not end with CRLFCRLF\n")); return -1; } /* find the header name */ colon_index = strchr (start_of_header, ':'); if (colon_index == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "End of header Not found\n")); return -1; /* this is also an error case */ } if (colon_index - start_of_header + 1 < 2) return -1; if (end_of_header <= colon_index) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Malformed message\n")); return -1; } hname = (char *) osip_malloc (colon_index - start_of_header + 1); osip_strncpy (hname, start_of_header, colon_index - start_of_header); osip_clrspace (hname); { const char *end; /* END of header is (end_of_header-2) if header separation is CRLF */ /* END of header is (end_of_header-1) if header separation is CR or LF */ if ((end_of_header[-2] == '\r') || (end_of_header[-2] == '\n')) end = end_of_header - 2; else end = end_of_header - 1; if ((end) - colon_index < 2) hvalue = NULL; /* some headers (subject) can be empty */ else { hvalue = (char *) osip_malloc ((end) - colon_index); osip_strncpy (hvalue, colon_index + 1, (end) - colon_index - 1); osip_clrspace (hvalue); } } /* hvalue MAY contains multiple value. In this case, they */ /* are separated by commas. But, a comma may be part of a */ /* quoted-string ("here, and there" is an example where the */ /* comma is not a separator!) */ i = msg_handle_multiple_values (sip, hname, hvalue); osip_free (hname); osip_free (hvalue); if (i == -1) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "End of header Not found\n")); return -1; } /* the list of headers MUST always end with */ /* CRLFCRLF (also CRCR and LFLF are allowed) */ if ((end_of_header[0] == '\r') || (end_of_header[0] == '\n')) { *body = end_of_header; return 0; /* end of header found */ } /* continue on the next header */ start_of_header = end_of_header; }/* Unreachable code OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_BUG, NULL, "This code cannot be reached\n")); */ return -1;}/* internal method to parse the body */intmsg_osip_body_parse (osip_message_t * sip, const char *start_of_buf, const char **next_body){ const char *start_of_body; const char *end_of_body; char *tmp; int i; char *sep_boundary; osip_generic_param_t *ct_param; /* if MIME-Version: does not exist we just have */ /* to deal with one body and no header... */ if (sip->mime_version == NULL) { /* Mime-Version header does NOT exist */ if (sip->content_type == NULL) return 0; /* no body is attached */ else { size_t osip_body_len; if (start_of_buf[0] == '\0') return -1; /* final CRLF is missing */ /* get rid of the first CRLF */ if ('\r' == start_of_buf[0]) { if ('\n' == start_of_buf[1]) start_of_body = start_of_buf + 2; else start_of_body = start_of_buf + 1; } else if ('\n' == start_of_buf[0]) start_of_body = start_of_buf + 1; else return -1; /* message does not end with CRLFCRLF, CRCR or LFLF */ if (sip->content_length != NULL) osip_body_len = osip_atoi (sip->content_length->value); else { /* if content_length does not exist, set it. */ char *tmp = osip_malloc (8); if (tmp == NULL) return -1; osip_body_len = strlen (start_of_body); sprintf (tmp, "%i", osip_body_len); i = osip_message_set_content_length (sip, tmp); osip_free (tmp); if (i != 0) return -1; } if (osip_body_len > strlen (start_of_body)) /* we do not receive the */ return -1; /* complete message */ /* end_of_body = start_of_body + strlen(start_of_body); */ end_of_body = start_of_body + osip_body_len; tmp = osip_malloc (end_of_body - start_of_body + 2); if (tmp == NULL) return -1; osip_strncpy (tmp, start_of_body, end_of_body - start_of_body); i = osip_message_set_body (sip, tmp); osip_free (tmp); if (i != 0) return -1; return 0; } } if (sip->content_type==NULL) return -1; /* find the boundary */ i = osip_generic_param_get_byname (sip->content_type->gen_params, "boundary", &ct_param); if (i != 0) return -1; if (ct_param == NULL) return -1; if (ct_param->gvalue == NULL) return -1; /* No boundary but multiple headers??? */ sep_boundary = (char *) osip_malloc (strlen (ct_param->gvalue) + 3); sprintf (sep_boundary, "--%s", ct_param->gvalue); *next_body = NULL; start_of_body = start_of_buf; for (;;) { i = __osip_find_next_occurence (sep_boundary, start_of_body, &start_of_body); if (i == -1) { osip_free (sep_boundary); return -1; } i = __osip_find_next_occurence (sep_boundary, start_of_body + strlen (sep_boundary), &end_of_body); if (i == -1) { osip_free (sep_boundary); return -1; } /* this is the real beginning of body */ start_of_body = start_of_body + strlen (sep_boundary) + 2; tmp = osip_malloc (end_of_body - start_of_body + 1); osip_strncpy (tmp, start_of_body, end_of_body - start_of_body); i = osip_message_set_body_mime (sip, tmp); osip_free (tmp); if (i == -1) { osip_free (sep_boundary); return -1; } if (strncmp (end_of_body + strlen (sep_boundary), "--", 2) == 0) { /* end of all bodies */ *next_body = end_of_body; osip_free (sep_boundary); return 0; } /* continue on the next body */ start_of_body = end_of_body; } /* Unreachable code */ /* osip_free (sep_boundary); */ return -1;}/* osip_message_t *sip is filled while analysing buf */intosip_message_parse (osip_message_t * sip, const char *buf){ int i; const char *next_header_index; char *tmp;#ifdef WIN32 tmp = _alloca (strlen(buf)+2);#else tmp = alloca (strlen(buf)+2);#endif osip_strncpy(tmp, buf, strlen(buf)); osip_util_replace_all_lws(tmp); /* parse request or status line */ i = __osip_message_startline_parse (sip, tmp, &next_header_index); if (i == -1) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not parse start line of message.\n")); return -1; } tmp = (char *) next_header_index; /* parse headers */ i = msg_headers_parse (sip, tmp, &next_header_index); if (i == -1) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "error in msg_headers_parse()\n")); return -1; } tmp = (char *) next_header_index; /* this is a *very* simple test... (which handle most cases...) */ if (strlen (tmp) < 3) { /* this is mantory in the oSIP stack */ if (sip->content_length == NULL) osip_message_set_content_length (sip, "0"); return 0; /* no body found */ } i = msg_osip_body_parse (sip, tmp, &next_header_index); if (i == -1) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "error in msg_osip_body_parse()\n")); return -1; } tmp = (char *) next_header_index; /* this is mandatory in the oSIP stack */ if (sip->content_length == NULL) osip_message_set_content_length (sip, "0"); return 0;}/* This method just add a received parameter in the Via as requested by rfc3261 */intosip_message_fix_last_via_header (osip_message_t * request, const char *ip_addr, int port){ osip_generic_param_t *rport; osip_via_t *via; /* get Top most Via header: */ if (request == NULL) return -1; if (MSG_IS_RESPONSE (request)) return 0; /* Don't fix Via header */ via = osip_list_get (request->vias, 0); if (via == NULL || via->host == NULL) /* Hey, we could build it? */ return -1; osip_via_param_get_byname (via, "rport", &rport); if (rport != NULL) { if (rport->gvalue == NULL) { rport->gvalue = (char *) osip_malloc (9);#if (defined WIN32 || defined _WIN32_WCE) _snprintf (rport->gvalue, 8, "%i", port);#else snprintf (rport->gvalue, 8, "%i", port);#endif } /* else bug? */ } /* only add the received parameter if the 'sent-by' value does not contains this ip address */ if (0 == strcmp (via->host, ip_addr)) /* don't need the received parameter */ return 0; osip_via_set_received (via, osip_strdup (ip_addr)); return 0;}const char *osip_message_get_reason (int replycode){ struct code_to_reason { int code; const char *reason; }; static const struct code_to_reason reasons1xx[] = { { 100, "Trying" }, { 180, "Ringing" }, { 181, "Call Is Being Forwarded" }, { 182, "Queued" }, { 183, "Session Progress" }, }; static const struct code_to_reason reasons2xx[] = { { 200, "OK" }, }; static const struct code_to_reason reasons3xx[] = { { 300, "Multiple Choices" }, { 301, "Moved Permanently" }, { 302, "Moved Temporarily" }, { 305, "Use Proxy" }, { 380, "Alternative Service" }, }; static const struct code_to_reason reasons4xx[] = { { 400, "Bad Request" }, { 401, "Unauthorized" }, { 402, "Payment Required" }, { 403, "Forbidden" }, { 404, "Not Found" }, { 405, "Method Not Allowed" }, { 406, "Not Acceptable" }, { 407, "Proxy Authentication Required" }, { 408, "Request Timeout" }, { 409, "Conflict" }, { 410, "Gone" }, { 411, "Length Required" }, { 413, "Request Entity Too Large" }, { 414, "Request-URI Too Large" }, { 415, "Unsupported Media Type" }, { 416, "Unsupported Uri Scheme" }, { 420, "Bad Extension" }, { 423, "Interval Too Short" }, { 480, "Temporarily not available" }, { 481, "Call Leg/Transaction Does Not Exist" }, { 482, "Loop Detected" }, { 483, "Too Many Hops" }, { 484, "Address Incomplete" }, { 485, "Ambiguous" }, { 486, "Busy Here" }, { 487, "Request Cancelled" }, { 488, "Not Acceptable Here" }, { 489, "Bad Event" }, }; static const struct code_to_reason reasons5xx[] = { { 500, "Internal Server Error" }, { 501, "Not Implemented" }, { 502, "Bad Gateway" }, { 503, "Service Unavailable" }, { 504, "Gateway Time-out" }, { 505, "SIP Version not supported" }, }; static const struct code_to_reason reasons6xx[] = { { 600, "Busy Everywhere" }, { 603, "Decline" }, { 604, "Does not exist anywhere" }, { 606, "Not Acceptable" } }; const struct code_to_reason *reasons; int len, i; switch (replycode / 100) { case 1: reasons = reasons1xx; len = sizeof(reasons1xx) / sizeof(*reasons); break; case 2: reasons = reasons2xx; len = sizeof(reasons2xx) / sizeof(*reasons); break; case 3: reasons = reasons3xx; len = sizeof(reasons3xx) / sizeof(*reasons); break; case 4: reasons = reasons4xx; len = sizeof(reasons4xx) / sizeof(*reasons); break; case 5: reasons = reasons5xx; len = sizeof(reasons5xx) / sizeof(*reasons); break; case 6: reasons = reasons6xx; len = sizeof(reasons6xx) / sizeof(*reasons); break; default: return NULL; } for (i = 0; i < len; i++) if (reasons[i].code == replycode) return reasons[i].reason; /* Not found. */ return NULL;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -