File uploading
FossilOrigin-Name: 8d7d245daca7e9a58256654103e005da7d41785ef2ec8e8153fd3a3730b3c0c3
This commit is contained in:
parent
f6291ca0ad
commit
22483e4e4a
7 changed files with 90 additions and 5 deletions
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -32,6 +32,8 @@ struct file_content
|
|||
{
|
||||
char* content;
|
||||
size_t content_size;
|
||||
char* filetype;
|
||||
char* filename;
|
||||
};
|
||||
|
||||
struct file_array
|
||||
|
|
54
src/status.c
54
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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
15
src/string.c
15
src/string.c
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue