Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[mms-lib] Added Name parameter to the part's Content-Type header
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.