-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathupload_file.c
111 lines (86 loc) · 3.1 KB
/
upload_file.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
/*
This file is part of toot.
toot is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
toot is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with toot. If not, see <https://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <curl/curl.h>
#include <json-c/json.h>
#include "asprintf.h"
#include "util.h"
int
upload_file(const char *path, const char *description, char **id_ptr)
{
struct config config;
if(load_config(&config) < 0) {
fprintf(stderr, "Error loading config");
return -1;
}
struct json_object *parsed_json;
struct json_object *json_media_id;
CURL *curl = curl_easy_init();
if(curl == NULL) {
fprintf(stderr, "Error creating libcurl thing\n");
return -1;
}
struct memory chunk = { 0 };
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, cb);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
char *url_to_post = NULL;
dm_asprintf(&url_to_post, "%s/api/v1/media", config.instance);
/* Don't repeat yourself, so they say, it's the root of all evil
* today */
char *header_fmt = "Authorization: Bearer %s";
struct curl_slist *header_list = NULL;
char *authorization_header = NULL;
dm_asprintf(&authorization_header, header_fmt, config.access_token);
header_list = curl_slist_append(header_list, authorization_header);
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list);
curl_mime *mime;
mime = curl_mime_init(curl);
curl_mimepart *image_part;
image_part = curl_mime_addpart(mime);
curl_mimepart *description_part;
description_part = curl_mime_addpart(mime);
/* Upload file */
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "");
curl_mime_filedata(image_part, path);
curl_mime_name(image_part, "file");
/* Description */
curl_mime_data(description_part, description, CURL_ZERO_TERMINATED);
curl_mime_name(description_part, "description");
/* Post */
curl_easy_setopt(curl, CURLOPT_MIMEPOST, mime);
curl_easy_setopt(curl, CURLOPT_URL, url_to_post);
/* Free the things */
CURLcode cret = curl_easy_perform(curl);
free(url_to_post);
curl_easy_cleanup(curl);
curl_mime_free(mime);
curl_slist_free_all(header_list);
/* Get the media id */
if(cret != CURLE_OK) {
/* response error problem */
printf("Error code %d (Stream error in the HTTP/2 framing layer.) occured when interactin with server.\n", cret);
printf("It's unlikely that the file '%s' was uploaded\n", path);
*id_ptr = NULL;
return -1;
}
parsed_json = json_tokener_parse(chunk.response);
json_object_object_get_ex(parsed_json, "id", &json_media_id);
const char *media_id = json_object_get_string(json_media_id);
*id_ptr = (char *)media_id;
free(parsed_json);
free_response(&chunk);
return 0;
}