File uploading

FossilOrigin-Name: 8d7d245daca7e9a58256654103e005da7d41785ef2ec8e8153fd3a3730b3c0c3
This commit is contained in:
me@ow.nekobit.net 2022-04-11 20:58:18 +00:00
parent f6291ca0ad
commit 22483e4e4a
7 changed files with 90 additions and 5 deletions

View file

@ -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;

View file

@ -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,

View file

@ -32,6 +32,8 @@ struct file_content
{
char* content;
size_t content_size;
char* filetype;
char* filename;
};
struct file_array

View file

@ -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;
}

View file

@ -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

View file

@ -16,6 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include <string.h>
#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;

View file

@ -21,6 +21,7 @@
#include <stddef.h>
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