|
|
|
@ -102,6 +102,23 @@ bool handle_post( struct http_request* req, struct account* a )
|
|
|
|
|
bool result = false;
|
|
|
|
|
struct status* s = NULL;
|
|
|
|
|
|
|
|
|
|
struct poll_params_t
|
|
|
|
|
{
|
|
|
|
|
int expires_in;
|
|
|
|
|
bool multiple;
|
|
|
|
|
struct {
|
|
|
|
|
char** items;
|
|
|
|
|
int count;
|
|
|
|
|
} options;
|
|
|
|
|
};
|
|
|
|
|
#define OBJ_TYPE struct poll_params_t
|
|
|
|
|
static struct json_object_field poll_params_layout[] = {
|
|
|
|
|
JSON_FIELD_INTEGER( expires_in, true ),
|
|
|
|
|
JSON_FIELD_BOOL( multiple, false ),
|
|
|
|
|
JSON_FIELD_ARRAY_OF_STRINGS( options, false ),
|
|
|
|
|
JSON_FIELD_END,
|
|
|
|
|
};
|
|
|
|
|
#undef OBJ_TYPE
|
|
|
|
|
struct params_t
|
|
|
|
|
{
|
|
|
|
|
struct {
|
|
|
|
@ -111,24 +128,14 @@ bool handle_post( struct http_request* req, struct account* a )
|
|
|
|
|
|
|
|
|
|
bool sensitive;
|
|
|
|
|
|
|
|
|
|
struct poll_params_t poll;
|
|
|
|
|
|
|
|
|
|
char* status;
|
|
|
|
|
char* visibility;
|
|
|
|
|
char* in_reply_to_id;
|
|
|
|
|
char* quote_id;
|
|
|
|
|
char* spoiler_text;
|
|
|
|
|
} params;
|
|
|
|
|
memset(¶ms,0,sizeof(params));
|
|
|
|
|
|
|
|
|
|
const char* indempotency_key = http_request_get_header( req, "Idempotency-Key" );
|
|
|
|
|
if( indempotency_key ) {
|
|
|
|
|
char* existing = ffdb_trie_get( "data/indempotency", indempotency_key );
|
|
|
|
|
if( existing ) {
|
|
|
|
|
s = status_from_id( atoi(existing) );
|
|
|
|
|
free( existing );
|
|
|
|
|
goto success;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#define OBJ_TYPE struct params_t
|
|
|
|
|
static struct json_object_field layout[] = {
|
|
|
|
|
JSON_FIELD_ARRAY_OF_STRINGS( media_ids, false ),
|
|
|
|
@ -138,10 +145,29 @@ bool handle_post( struct http_request* req, struct account* a )
|
|
|
|
|
JSON_FIELD_STRING( in_reply_to_id, false ),
|
|
|
|
|
JSON_FIELD_STRING( quote_id, false ),
|
|
|
|
|
JSON_FIELD_STRING( spoiler_text, false ),
|
|
|
|
|
{
|
|
|
|
|
.key = "poll",
|
|
|
|
|
.offset = offsetof( OBJ_TYPE, poll ),
|
|
|
|
|
.required = false,
|
|
|
|
|
.type = &json_field_object_composite,
|
|
|
|
|
.composite_layout = poll_params_layout,
|
|
|
|
|
},
|
|
|
|
|
JSON_FIELD_END,
|
|
|
|
|
};
|
|
|
|
|
#undef OBJ_TYPE
|
|
|
|
|
|
|
|
|
|
memset(¶ms,0,sizeof(params));
|
|
|
|
|
|
|
|
|
|
const char* indempotency_key = http_request_get_header( req, "Idempotency-Key" );
|
|
|
|
|
if( indempotency_key ) {
|
|
|
|
|
char* existing = ffdb_trie_get( "data/indempotency", indempotency_key );
|
|
|
|
|
if( existing ) {
|
|
|
|
|
s = status_from_id( atoi(existing) );
|
|
|
|
|
free( existing );
|
|
|
|
|
goto success;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
FILE* data = http_request_get_request_data( req );
|
|
|
|
|
if( !json_read_object_layout_from_FILE( data, layout, ¶ms ) ) { goto failed; }
|
|
|
|
|
|
|
|
|
@ -151,6 +177,28 @@ bool handle_post( struct http_request* req, struct account* a )
|
|
|
|
|
s->published = time(NULL);
|
|
|
|
|
s->source = strdup( params.status );
|
|
|
|
|
|
|
|
|
|
// Handle poll
|
|
|
|
|
if( params.poll.options.count > 0 ) {
|
|
|
|
|
struct status_poll* poll;
|
|
|
|
|
poll = malloc(sizeof(*poll));
|
|
|
|
|
memset(poll,0,sizeof(*poll));
|
|
|
|
|
s->poll = poll;
|
|
|
|
|
|
|
|
|
|
poll->expires_at = time(NULL) + params.poll.expires_in;
|
|
|
|
|
|
|
|
|
|
for( int i = 0; i < params.poll.options.count; ++i ) {
|
|
|
|
|
struct status_poll_option* option;
|
|
|
|
|
option = malloc(sizeof(*option));
|
|
|
|
|
memset(option,0,sizeof(*option));
|
|
|
|
|
|
|
|
|
|
option->title = params.poll.options.items[i];
|
|
|
|
|
params.poll.options.items[i] = NULL;
|
|
|
|
|
|
|
|
|
|
array_append( &poll->options, sizeof(option), &option );
|
|
|
|
|
}
|
|
|
|
|
free( params.poll.options.items );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if( 0 == strcmp( "direct", params.visibility ) ) {
|
|
|
|
|
s->visibility = status_visibility_direct;
|
|
|
|
|
}
|
|
|
|
@ -487,7 +535,9 @@ bool route_polls( struct http_request* req )
|
|
|
|
|
if( !s->poll ) { goto failed; }
|
|
|
|
|
|
|
|
|
|
if( http_request_route_term( req, "votes" ) ) {
|
|
|
|
|
if( handle_votes( req, s ) ) { goto success; }
|
|
|
|
|
if( http_request_route_method( req, "POST" ) ) {
|
|
|
|
|
if( handle_votes( req, s ) ) { goto success; }
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
goto failed;
|
|
|
|
|