📄 mime.c
字号:
/* mapping function required to pass recurssion level */ mime = mime_entity_to_octstr_real(m, 0); return mime;}/* * This routine is used for mime_[http|octstr]_to_entity() in order to * reduce code duplication. Basically the only difference is how the headers * are parsed or passed to the resulting MIMEEntity representation. */static MIMEEntity *mime_something_to_entity(Octstr *mime, List *headers){ MIMEEntity *e; ParseContext *context; Octstr *value, *boundary, *start; int len = 0; gw_assert(mime != NULL); value = boundary = start = NULL; context = parse_context_create(mime); e = mime_entity_create(); /* parse the headers up to the body. If we have headers already passed * from our caller, then duplicate them and continue */ if (headers != NULL) { /* duplicate existing headers */ e->headers = http_header_duplicate(headers); } else { /* parse the headers out of the mime block */ if ((read_mime_headers(context, e->headers) != 0) || e->headers == NULL) { debug("mime.parse",0,"Failed to read MIME headers in Octstr block:"); octstr_dump(mime, 0); mime_entity_destroy(e); parse_context_destroy(context); return NULL; } } /* * Now check if the body is a multipart. This is indicated by an 'boundary' * parameter in the 'Content-Type' value. If yes, call ourself for the * multipart entities after parsing them. */ value = http_header_value(e->headers, octstr_imm("Content-Type")); boundary = http_get_header_parameter(value, octstr_imm("boundary")); start = http_get_header_parameter(value, octstr_imm("start")); /* Beware that we need *unquoted* strings to compare against in the * following parsing sections. */ if (boundary && (len = octstr_len(boundary)) > 0 && octstr_get_char(boundary, 0) == '"' && octstr_get_char(boundary, len-1) == '"') { octstr_delete(boundary, 0, 1); octstr_delete(boundary, len-2, 1); } if (start && (len = octstr_len(start)) > 0 && octstr_get_char(start, 0) == '"' && octstr_get_char(start, len-1) == '"') { octstr_delete(start, 0, 1); octstr_delete(start, len-2, 1); } if (boundary != NULL) { /* we have a multipart block as body, parse the boundary blocks */ Octstr *entity, *seperator, *os; /* loop by all boundary blocks we have in the body */ seperator = octstr_create("--"); octstr_append(seperator, boundary); while ((entity = parse_get_seperated_block(context, seperator)) != NULL) { MIMEEntity *m; Octstr *cid = NULL; /* we have still two linefeeds at the beginning and end that we * need to remove, these are from the separator. * We check if it is \n or \r\n?! */ if (octstr_get_char(entity, 0) == '\r') octstr_delete(entity, 0, 2); else octstr_delete(entity, 0, 1); if (octstr_get_char(entity, octstr_len(entity) - 2) == '\r') octstr_delete(entity, octstr_len(entity) - 4, 4); else octstr_delete(entity, octstr_len(entity) - 2, 2); debug("mime.parse",0,"MIME multipart: Parsing entity:"); octstr_dump(entity, 0); /* call ourself for this MIME entity and inject to list */ m = mime_octstr_to_entity(entity); list_append(e->multiparts, m); /* check if this entity is our start entity (in terms of related) * and set our start pointer to it */ if (start != NULL && (cid = http_header_value(m->headers, octstr_imm("Content-ID"))) != NULL && octstr_compare(start, cid) == 0) { /* set only if none has been set before */ e->start = (e->start == NULL) ? m : e->start; } octstr_destroy(cid); octstr_destroy(entity); } /* ok, we parsed all blocks, we expect to see now the end boundary */ octstr_append_cstr(seperator, "--"); os = parse_get_line(context); if (os != NULL && octstr_compare(os, seperator) != 0) { debug("mime.parse",0,"Failed to see end boundary, parsed line is '%s'.", octstr_get_cstr(os)); } octstr_destroy(seperator); octstr_destroy(os); } else { /* we don't have boundaries, so this is no multipart block, * pass the body to the MIME entity. */ e->body = parse_get_rest(context); } parse_context_destroy(context); octstr_destroy(value); octstr_destroy(boundary); octstr_destroy(start); return e;}MIMEEntity *mime_octstr_to_entity(Octstr *mime){ gw_assert(mime != NULL); return mime_something_to_entity(mime, NULL);}MIMEEntity *mime_http_to_entity(List *headers, Octstr *body){ gw_assert(headers != NULL && body != NULL); return mime_something_to_entity(body, headers);}List *mime_entity_headers(MIMEEntity *m){ List *headers; gw_assert(m != NULL && m->headers != NULL); headers = http_header_duplicate(m->headers); return headers;}Octstr *mime_entity_body(MIMEEntity *m){ Octstr *os, *body; ParseContext *context; MIMEEntity *e; gw_assert(m != NULL && m->headers != NULL); os = mime_entity_to_octstr(m); context = parse_context_create(os); e = mime_entity_create(); /* parse the headers up to the body */ if ((read_mime_headers(context, e->headers) != 0) || e->headers == NULL) { debug("mime.parse",0,"Failed to read MIME headers in Octstr block:"); octstr_dump(os, 0); mime_entity_destroy(e); parse_context_destroy(context); return NULL; } /* the rest is the body */ body = parse_get_rest(context); octstr_destroy(os); mime_entity_destroy(e); parse_context_destroy(context); return body;}/******************************************************************** * Routines for debugging purposes. */static void mime_entity_dump_real(MIMEEntity *m, unsigned int level){ long i, items; Octstr *prefix, *type, *charset; unsigned int j; gw_assert(m != NULL && m->headers != NULL); prefix = octstr_create(""); for (j = 0; j < level * 2; j++) octstr_append_cstr(prefix, " "); http_header_get_content_type(m->headers, &type, &charset); debug("mime.dump",0,"%sContent-Type `%s'", octstr_get_cstr(prefix), octstr_get_cstr(type)); if (m->start != NULL) { Octstr *cid = http_header_value(m->start->headers, octstr_imm("Content-ID")); debug("mime.dump",0,"%sRelated to Content-ID <%s> MIMEEntity at address `%p'", octstr_get_cstr(prefix), octstr_get_cstr(cid), m->start); octstr_destroy(cid); } items = list_len(m->multiparts); debug("mime.dump",0,"%sBody contains %ld MIME entities, size %ld", octstr_get_cstr(prefix), items, (items == 0 && m->body) ? octstr_len(m->body) : -1); octstr_destroy(prefix); octstr_destroy(type); octstr_destroy(charset); for (i = 0; i < items; i++) { MIMEEntity *e = list_get(m->multiparts, i); mime_entity_dump_real(e, level + 1); }}void mime_entity_dump(MIMEEntity *m){ gw_assert(m != NULL && m->headers != NULL); debug("mms",0,"Dumping MIMEEntity at address %p", m); mime_entity_dump_real(m, 0);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -