You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.4 KiB
C

#include "http_server/http_request.h"
#include "controller/mastodon_api.h"
#include "controller/oauth.h"
#include "controller/webfinger.h"
#include "controller/nodeinfo.h"
#include "controller/owner.h"
#include "controller/inbox.h"
#include <string.h>
#include <stdlib.h>
const char* mime_type_for_filename( const char* filename )
{
// determine MIME type
int len = strlen(filename);
struct {
const char* extension;
const char* mime_type;
} extensions[] = {
{ ".html", "text/html" },
{ ".js", "application/javascript" },
{ ".png", "image/png" },
{ ".jpg", "image/jpg" },
{ ".css", "text/css" },
{ ".json", "application/json" },
{ ".svg", "image/svg+xml" },
{ ".woff", "font/woff" },
{ ".woff2", "font/woff2" },
{ ".mp3", "audio/mp3" },
{ ".ogg", "audio/ogg" },
{ ".oga", "audio/ogg" },
{ NULL, NULL },
};
for( int i = 0; extensions[i].extension; ++i ) {
int s = strlen( extensions[i].extension );
if( 0 == strcmp( extensions[i].extension, &filename[len-s] ) ) {
return extensions[i].mime_type;
}
}
return NULL;
}
static bool send_asset( struct http_request* req, const char* fs_path )
{
const char* mime_type = mime_type_for_filename(fs_path);
if( !mime_type ) {
printf( "Unable to determine MIME type for %s\n", fs_path );
return false;
}
return http_request_send_file( req, fs_path, mime_type );
}
bool route_asset( struct http_request* req )
{
bool result = false;
char* full_path = NULL;
// Don't allow ".." in the path
full_path = strdup(http_request_get_full_path( req ));
if( strstr( full_path, ".." ) ) { goto failed; }
// Cut off the query string
char* res;
strtok_r( full_path, "?", &res );
// Handle index
if( full_path[ strlen(full_path)-1 ] == '/' ) {
free(full_path);
return send_asset( req, "assets/soapbox/index.html" );
}
struct {
const char* fs_path;
const char* where;
} fs_mounts[] = {
{ "assets/soapbox", "/" },
{ "data/config/assets", "/" },
{ NULL, NULL }
};
char filename[512];
for( int i = 0; fs_mounts[i].fs_path; ++i ) {
int ws = strlen( fs_mounts[i].where );
if( 0 == strncmp( fs_mounts[i].where, full_path, ws ) ) {
snprintf( filename, sizeof(filename), "%s/%s", fs_mounts[i].fs_path, &full_path[ws] );
printf( "Trying %s\n", filename );
FILE* f = fopen(filename,"r");
if( f ) {
fclose(f);
if( send_asset( req, filename ) ) {
goto success;
} else {
goto failed;
}
}
}
}
goto failed;
failed:
printf( "failed to process asset: %s\n", full_path );
result = false;
goto cleanup;
success:
result = true;
goto cleanup;
cleanup:
free(full_path);
return result;
}
bool route_request( struct http_request* req )
{
if( http_request_route( req, "/api/v1/" ) ) {
return route_mastodon_api( req );
} else if( http_request_route( req, "/oauth" ) ) {
return route_oauth( req );
} else if( http_request_route( req, "/owner" ) ) {
return route_owner( req );
} else if( http_request_route( req, "/inbox" ) ) {
return route_inbox( req );
} else if( http_request_route( req, "/.well-known" ) ) {
if( http_request_route( req, "/webfinger?" ) ) {
return route_wellknown_webfinger( req );
} else if( http_request_route( req, "/nodeinfo" ) ) {
printf( "Nodeinfo\n" );
return route_wellknown_nodeinfo( req );
}
} else if( http_request_route( req, "/nodeinfo" ) ) {
return route_nodeinfo(req);
} else {
return route_asset(req);
}
return false;
}