Skip to content

Commit

Permalink
[mms-lib] Added Name parameter to the part's Content-Type header
Browse files Browse the repository at this point in the history
That's one of the ways to pass the name of the attachment to the recipient.
And this is what most MMS implementations are doing nowadays.
  • Loading branch information
monich committed May 16, 2014
1 parent 75b042f commit 198ea97
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 18 deletions.
43 changes: 33 additions & 10 deletions mms-lib/src/mms_attachment.c
Expand Up @@ -28,6 +28,7 @@
MMS_LOG_MODULE_DEFINE("mms-attachment");

#define MMS_ATTACHMENT_DEFAULT_TYPE "application/octet-stream"
#define CONTENT_TYPE_PARAM_NAME "name"

G_DEFINE_TYPE(MMSAttachment, mms_attachment, G_TYPE_OBJECT);

Expand Down Expand Up @@ -250,50 +251,70 @@ mms_attachment_new(
GMappedFile* map = g_mapped_file_new(path, FALSE, error);
if (map) {
unsigned int flags = 0;
char* media_type = NULL;
char* name = g_path_get_basename(path);
char* content_type = NULL;
GType type;
MMSAttachment* at;

if (info->content_type && info->content_type[0]) {
char** ct = mms_parse_http_content_type(info->content_type);
if (ct) {
content_type = mms_unparse_http_content_type(ct);
char** ptr;
gboolean append_name = TRUE;
if (!strcmp(ct[0], SMIL_CONTENT_TYPE)) {
flags |= MMS_ATTACHMENT_SMIL;
}
for (ptr = ct+1; *ptr; ptr+=2) {
if (!g_ascii_strcasecmp(ptr[0], CONTENT_TYPE_PARAM_NAME)) {
g_free(ptr[1]);
ptr[1] = g_strdup(name);
append_name = FALSE;
}
}
if (append_name) {
const guint len = g_strv_length(ct);
ct = g_renew(gchar*, ct, len+3);
ct[len] = g_strdup(CONTENT_TYPE_PARAM_NAME);
ct[len+1] = g_strdup(name);
ct[len+2] = NULL;
}
content_type = mms_unparse_http_content_type(ct);
media_type = g_strdup(ct[0]);
g_strfreev(ct);
}
}

if (!content_type) {
char* detected_type = mms_attachment_guess_content_type(path);
const char* default_charset = "utf-8";
const char* charset = NULL;
const char* ct[4];
const char* ct[6];
int n = 0;

if (!strcmp(detected_type, SMIL_CONTENT_TYPE)) {
media_type = mms_attachment_guess_content_type(path);
if (!strcmp(media_type, SMIL_CONTENT_TYPE)) {
flags |= MMS_ATTACHMENT_SMIL;
charset = default_charset;
} else if (g_str_has_prefix(detected_type, "text/")) {
} else if (g_str_has_prefix(media_type, "text/")) {
charset = default_charset;
}

ct[n++] = detected_type;
ct[n++] = media_type;
if (charset) {
ct[n++] = "charset";
ct[n++] = charset;
}
ct[n++] = CONTENT_TYPE_PARAM_NAME;
ct[n++] = name;
ct[n++] = NULL;
content_type = mms_unparse_http_content_type((char**)ct);
g_free(detected_type);
}

MMS_DEBUG("%s: %s", path, content_type);

if (!strcmp(content_type, "image/jpeg")) {
if (!strcmp(media_type, "image/jpeg")) {
type = MMS_TYPE_ATTACHMENT_JPEG;
} else if (g_str_has_prefix(content_type, "image/")) {
} else if (g_str_has_prefix(media_type, "image/")) {
type = MMS_TYPE_ATTACHMENT_IMAGE;
} else {
type = MMS_TYPE_ATTACHMENT;
Expand All @@ -305,10 +326,12 @@ mms_attachment_new(
at->flags |= flags;
at->file_name = at->original_file = path;
at->content_type = content_type;
at->content_location = g_path_get_basename(path);
at->content_location = name;
at->content_id = (info->content_id && info->content_id[0]) ?
g_strdup(info->content_id) :
g_strdup(at->content_location);

g_free(media_type);
return at;
}
g_free(path);
Expand Down
38 changes: 33 additions & 5 deletions mms-lib/src/mms_codec.c
Expand Up @@ -32,10 +32,8 @@
# define ssize_t int
# define write _write
# include <io.h>
# define uninitialized_var(x) x
#else
# include <unistd.h>
# define uninitialized_var(x) x = x
#endif

#include <glib.h>
Expand Down Expand Up @@ -1853,6 +1851,25 @@ static gboolean encode_quoted_string(struct file_buffer *fb,
{
char *ptr;
char **text = user;

if (!*text)
return TRUE;

ptr = fb_request_field(fb, header, strlen(*text) + 2);
if (ptr == NULL)
return FALSE;

ptr[0] = '"';
strcpy(ptr + 1, *text);

return TRUE;
}

static gboolean encode_content_id(struct file_buffer *fb,
enum mms_header header, void *user)
{
char *ptr;
char **text = user;
unsigned int len;

if (!*text)
Expand Down Expand Up @@ -2067,7 +2084,7 @@ static gboolean mms_encode_send_req_part_header(struct mms_attachment *part,
unsigned int ct_len;
unsigned int cs_len;
const char *ct_str;
const char *uninitialized_var(cs_str);
char *name = NULL;
unsigned int ctp_len;
unsigned int cid_len;
unsigned int cloc_len;
Expand Down Expand Up @@ -2099,7 +2116,7 @@ static gboolean mms_encode_send_req_part_header(struct mms_attachment *part,
const char *key = parsed[i];

if (g_ascii_strcasecmp("charset", key) == 0) {
cs_str = parsed[i+1];
const char *cs_str = parsed[i+1];

len += 1;

Expand All @@ -2111,6 +2128,10 @@ static gboolean mms_encode_send_req_part_header(struct mms_attachment *part,
goto done;

len += cs_len;

} else if (g_ascii_strcasecmp("name", key) == 0) {
name = parsed[i+1];
len += 2 + strlen(name) + 1;
}
}

Expand Down Expand Up @@ -2179,9 +2200,16 @@ static gboolean mms_encode_send_req_part_header(struct mms_attachment *part,
memcpy(ptr, &cs_val, cs_len);
}

/* Encode "name" param */
if (name) {
if (encode_quoted_string(fb, WSP_PARAMETER_TYPE_NAME_DEFUNCT,
&name) == FALSE)
goto done;
}

/* Encode content-id */
if (part->content_id != NULL) {
if (encode_quoted_string(fb, MMS_PART_HEADER_CONTENT_ID,
if (encode_content_id(fb, MMS_PART_HEADER_CONTENT_ID,
&part->content_id) == FALSE)
goto done;
}
Expand Down
6 changes: 3 additions & 3 deletions mms-lib/test/send/test_send.c
Expand Up @@ -80,9 +80,9 @@ typedef struct test {
} Test;

static const MMSAttachmentInfo test_files_accept [] = {
{ "smil", NULL, NULL },
{ "0001.jpg", "image/jpeg", "image" },
{ "test.txt", "text/plain;charset=utf-8", "text" }
{ "smil", "application/smil;charset=us-ascii", NULL },
{ "0001.jpg", "image/jpeg;name=0001.jpg", "image" },
{ "test.txt", "text/plain;charset=utf-8;name=wrong.name", "text" }
};

static const MMSAttachmentInfo test_files_accept_no_ext [] = {
Expand Down

0 comments on commit 198ea97

Please sign in to comment.