diff --git a/src/mime.c b/src/mime.c index a4b2702..8cd9609 100644 --- a/src/mime.c +++ b/src/mime.c @@ -26,6 +26,10 @@ char* get_mime_boundary(char* content_type_str, char** bound) { + // If neither values are set, get out + if (!(getenv("CONTENT_TYPE") || content_type_str)) + return NULL; + char* content = content_type_str ? content_type_str : getenv("CONTENT_TYPE"); // Data gets changed in place @@ -170,8 +174,8 @@ char* read_form_data(char* boundary, begin_to_value_size = info->value - begin; // Look for end - if ((r = strstr(r, boundary)) && - r && strstr(r-4, "\r\n--")) + if ((r = strnstr(r, boundary, size - begin_to_value_size)) && + r && strnstr(r-4, "\r\n--", size - begin_to_value_size)) { r[-4] = '\0'; data_size = (r-4) - info->value; diff --git a/src/query.c b/src/query.c index 030af86..921df49 100644 --- a/src/query.c +++ b/src/query.c @@ -86,6 +86,8 @@ void key_files(char* val, struct form_props* form, void* arg) // Store arr->content[arr->array_size-1].content = ptr; arr->content[arr->array_size-1].content_size = form->data_size; + arr->content[arr->array_size-1].filename = form->filename; + arr->content[arr->array_size-1].filetype = form->filetype; return; @@ -98,6 +100,7 @@ char* read_post_data(struct query_values* post) struct http_form_info form_info; struct form_props form_props; char* request_method = getenv("REQUEST_METHOD"); + char* content_length = getenv("CONTENT_LENGTH"); char* post_query = NULL, *p_query_read; // BEGIN Query references @@ -120,7 +123,9 @@ char* read_post_data(struct query_values* post) }; // END Query references - if (request_method && strcmp("POST", request_method) == 0) + if (request_method && + strcmp("POST", request_method) == 0 && + content_length) { char* mime_boundary; char* mime_mem = get_mime_boundary(NULL, &mime_boundary); @@ -144,7 +149,7 @@ char* read_post_data(struct query_values* post) if (mime_mem) { // Get size from here to the end - begin_curr_size = p_query_read - p_query; + begin_curr_size = p_query_read - post_query; // Mime value p_query_read = read_form_data(mime_boundary, p_query_read, diff --git a/src/query.h b/src/query.h index f89a6b5..06d7173 100644 --- a/src/query.h +++ b/src/query.h @@ -32,6 +32,8 @@ struct file_content { char* content; size_t content_size; + char* filetype; + char* filename; }; struct file_array diff --git a/src/status.c b/src/status.c index c08f957..0b55182 100644 --- a/src/status.c +++ b/src/status.c @@ -46,6 +46,52 @@ struct status_args struct mstdnt_status* status; }; +// TODO move to attachments.c +int try_upload_media(struct session* ssn, + mastodont_t* api, + char*** media_ids) +{ + struct mstdnt_attachment attachment; + struct mstdnt_storage storage; + + if (!ssn->post.files.array_size) + return 1; + *media_ids = malloc(sizeof(char*) * ssn->post.files.array_size); + + for (int i = 0; i < ssn->post.files.array_size; ++i) + { + struct file_content* content = ssn->post.files.content + i; + struct mstdnt_upload_media_args args = { + .file = { + .file = content->content, + .filename = content->filename, + .filesize = content->content_size, + .filetype = content->filetype, + }, + .thumbnail = NULL, + .description = "Treebird image" + }; + + mastodont_upload_media(api, + &args, + &storage, + &attachment); + + (*media_ids)[i] = malloc(strlen(attachment.id)+1); + strcpy((*media_ids)[i], attachment.id); + } + + return 0; +} + +void cleanup_media_ids(struct session* ssn, char** media_ids) +{ + if (!media_ids) return; + for (size_t i = 0; i < ssn->post.files.array_size; ++i) + free(media_ids[i]); + free(media_ids); +} + int try_post_status(struct session* ssn, mastodont_t* api) { if (!(ssn->post.content)) return 1; @@ -54,6 +100,10 @@ int try_post_status(struct session* ssn, mastodont_t* api) char** files; size_t files_len; + char** media_ids = NULL; + + // Upload images + try_upload_media(ssn, api, &media_ids); // Cookie copy and read struct mstdnt_args args = { @@ -62,7 +112,8 @@ int try_post_status(struct session* ssn, mastodont_t* api) .in_reply_to_conversation_id = NULL, .in_reply_to_id = ssn->post.replyid, .language = NULL, - .media_ids = NULL, + .media_ids = media_ids, + .media_ids_len = media_ids ? ssn->post.files.array_size : 0, .poll = NULL, .preview = 0, .scheduled_at = NULL, @@ -76,6 +127,7 @@ int try_post_status(struct session* ssn, mastodont_t* api) // TODO cleanup when errors are properly implemented mastodont_storage_cleanup(&storage); + cleanup_media_ids(ssn, media_ids); return 0; } diff --git a/src/status.h b/src/status.h index 76a0f63..0a10f2a 100644 --- a/src/status.h +++ b/src/status.h @@ -28,6 +28,9 @@ #define STATUS_EMOJI_PICKER (1<<1) char* construct_in_reply_to(mastodont_t* api, struct mstdnt_status* status, size_t* size); +int try_upload_media(struct session* ssn, + mastodont_t* api, + char*** media_ids); int try_post_status(struct session* ssn, mastodont_t* api); int try_interact_status(struct session* ssn, mastodont_t* api, char* id); void content_status_create(struct session* ssn, mastodont_t* api, char** data); @@ -47,4 +50,7 @@ void status_interact(struct session* ssn, mastodont_t* api, char** data); // Above wraps to the below function void content_status(struct session* ssn, mastodont_t* api, char** data, int is_reply); +// Cleanup +void cleanup_media_ids(struct session* ssn, char** media_ids); + #endif // STATUS_H diff --git a/src/string.c b/src/string.c index 121de95..7d29603 100644 --- a/src/string.c +++ b/src/string.c @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +#include #include "string.h" int streql(char* cmp1, char* cmp2) @@ -27,10 +28,24 @@ int streql(char* cmp1, char* cmp2) return 1; } + +int strneql(char* cmp1, char* cmp2, size_t cmp1_n) +{ + for (size_t i = 0; i < cmp1_n; ++i) + if (*cmp1++ != *cmp2++) + return 0; + + return 1; +} + + char* strnstr(const char* haystack, const char* needle, size_t s) { + size_t needle_len = strlen(needle); for (size_t i = 0; i < s; ++i) { + if (strneql(needle, haystack + i, needle_len)) + return haystack + i; } return NULL; diff --git a/src/string.h b/src/string.h index 1092a7e..4b7de8a 100644 --- a/src/string.h +++ b/src/string.h @@ -21,6 +21,7 @@ #include int streql(char* cmp1, char* cmp2); +int strneql(char* cmp1, char* cmp2, size_t cmp1_n); char* strnstr(const char* haystack, const char* needle, size_t s); #endif // TREE_STRING_H