parent
3c2f038ecc
commit
22bae76274
@ -1 +1 @@
|
||||
Subproject commit c1a1148184cd335366b97a2efaae116a526b6de9
|
||||
Subproject commit 1ff885b9b810503a2d98b8f78fb749ed07cd7ccf
|
@ -1 +1 @@
|
||||
Subproject commit af6ffed1c98d57b754692ab8f55467a5215a3bd2
|
||||
Subproject commit 44a552b831da2c1d9556fe909b6c77614f99a59e
|
@ -1 +1 @@
|
||||
Subproject commit 934dcd3d7f92975680b7c1a4574a86010417c7c7
|
||||
Subproject commit 1d59e38974df4022d3d84af7ae8e765b76611461
|
@ -1,48 +1,114 @@
|
||||
#define _GNU_SOURCE
|
||||
#include "fetch.h"
|
||||
|
||||
// Submodules
|
||||
#include "http/client/client.h"
|
||||
#include "util/format.h"
|
||||
#include "ap/object.h"
|
||||
#include "sha256/sha256.h"
|
||||
|
||||
// Standard Library
|
||||
#include <sys/stat.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
bool pull_remote_file( const char* filename, const char* uri )
|
||||
static bool do_fetch( const char* uri, FILE* result )
|
||||
{
|
||||
printf( "* Fetching %s\n", uri );
|
||||
char tmp_filename[512];
|
||||
FILE* f = fopen(format(tmp_filename,512,"%s.tmp",filename),"w");
|
||||
|
||||
long status_code = -1;
|
||||
long status_code;
|
||||
const void* request[] = {
|
||||
HTTP_REQ_URL, uri,
|
||||
HTTP_REQ_HEADER, "Accept: application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"",
|
||||
HTTP_REQ_OUTFILE, f,
|
||||
HTTP_REQ_OUTFILE, result,
|
||||
HTTP_REQ_RESULT_STATUS, &status_code,
|
||||
NULL,
|
||||
};
|
||||
printf( "GET %s\n", uri );
|
||||
if( !http_client_do( request ) ) {
|
||||
printf( "GET %s -> %ld\n", uri, status_code );
|
||||
printf( "! Unable to fetch %s\n", uri );
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
printf( "GET %s -> %ld\n", uri, status_code );
|
||||
|
||||
printf( "status_code = %ld\n", status_code );
|
||||
if( status_code == 200 ) {
|
||||
// success
|
||||
fclose(f);
|
||||
rename(tmp_filename,filename);
|
||||
return true;
|
||||
} else if( status_code == 401 ) {
|
||||
// Not Authorized
|
||||
if( status_code == 401 ) {
|
||||
// TODO: do signed fetch
|
||||
printf( "TODO: perform signed fetch\n" );
|
||||
fclose(f);
|
||||
return false;
|
||||
}
|
||||
return ( status_code == 200 );
|
||||
}
|
||||
|
||||
// Failure
|
||||
bool pull_remote_file( const char* filename, const char* uri )
|
||||
{
|
||||
printf( "* Fetching %s\n", uri );
|
||||
char tmp_filename[512];
|
||||
FILE* f = fopen(format(tmp_filename,512,"%s.tmp",filename),"w");
|
||||
|
||||
bool result = false;
|
||||
if( do_fetch( uri, f ) ) {
|
||||
rename(tmp_filename,filename);
|
||||
result = true;
|
||||
}
|
||||
fclose(f);
|
||||
return false;
|
||||
|
||||
return result;
|
||||
}
|
||||
bool pull_remote_file_if_older( const char* filename, const char* uri, int seconds )
|
||||
{
|
||||
struct stat s;
|
||||
char tmp_filename[512];
|
||||
snprintf( tmp_filename,512, "%s.tmp", filename );
|
||||
|
||||
// Skip download if .tmp file exists from a failed fetch and is within the timeout window
|
||||
if( 0 == stat(tmp_filename, &s ) ) {
|
||||
if( time(NULL) - s.st_mtime <= seconds ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if( 0 != stat(filename, &s ) ) { goto pull; }
|
||||
if( time(NULL) - s.st_mtime > seconds ) { goto pull; }
|
||||
|
||||
return true;
|
||||
pull:
|
||||
return pull_remote_file( filename, uri );
|
||||
}
|
||||
|
||||
char* fetch_remote_file_to_cache( const char* uri, int seconds )
|
||||
{
|
||||
char* filename = NULL;
|
||||
char hash[65];
|
||||
sha256_easy_hash_hex( uri, strlen(uri), hash );
|
||||
hash[64] = 0;
|
||||
|
||||
mkdir( "data/cache", 0755 );
|
||||
|
||||
asprintf( &filename, "data/cache/%s.dat", hash );
|
||||
printf( "Using %s for %s\n", filename, uri );
|
||||
|
||||
if( !pull_remote_file_if_older(filename,uri,seconds) ) {
|
||||
free(filename);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
enum {
|
||||
LIFE = 60*60*24*2 // 2 days
|
||||
};
|
||||
|
||||
struct ap_object* fetch_ap_object_ref( const char* uri )
|
||||
{
|
||||
char* filename = fetch_remote_file_to_cache(uri, LIFE );
|
||||
|
||||
if( !filename ) { return NULL; }
|
||||
|
||||
struct ap_object* res = ap_object_from_file(filename);
|
||||
free(filename);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
Reference in new issue