Improvements to URL metadata collection
Still not perfect - some corruption of data.
This commit is contained in:
parent
2258b13cc9
commit
eb49ca4e2d
77
src/io/io.c
77
src/io/io.c
|
@ -1,7 +1,10 @@
|
||||||
/*
|
/*
|
||||||
* io.c
|
* io.c
|
||||||
*
|
*
|
||||||
* Communication between PSSE and the outside world, via libcurl.
|
* Communication between PSSE and the outside world, via libcurl. NOTE
|
||||||
|
* that this file destructively changes metadata on URL connections,
|
||||||
|
* because the metadata is not available until the stream has been read
|
||||||
|
* from. It would be better to find a workaround!
|
||||||
*
|
*
|
||||||
* (c) 2019 Simon Brooke <simon@journeyman.cc>
|
* (c) 2019 Simon Brooke <simon@journeyman.cc>
|
||||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||||
|
@ -24,6 +27,8 @@
|
||||||
#include "consspaceobject.h"
|
#include "consspaceobject.h"
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "fopen.h"
|
#include "fopen.h"
|
||||||
|
#include "integer.h"
|
||||||
|
#include "intern.h"
|
||||||
#include "lispops.h"
|
#include "lispops.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -264,18 +269,47 @@ char *trim( char *s ) {
|
||||||
return ( char * ) &s[i];
|
return ( char * ) &s[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void maybe_add_status_meta(struct cons_space_object *cell) {
|
||||||
|
struct cons_pointer status_key = c_string_to_lisp_keyword( L"status-code" );
|
||||||
|
|
||||||
|
debug_print(L"maybe_add_status_meta: entered\n", DEBUG_IO);
|
||||||
|
|
||||||
|
if (cell->payload.stream.stream->type == CFTYPE_CURL &&
|
||||||
|
nilp(c_assoc( status_key, cell->payload.stream.meta))) {
|
||||||
|
long status = 0;
|
||||||
|
curl_easy_getinfo(cell->payload.stream.stream->handle.curl,
|
||||||
|
CURLINFO_RESPONSE_CODE,
|
||||||
|
&status);
|
||||||
|
|
||||||
|
debug_printf( DEBUG_IO, L"maybe_add_status_meta: read HTTP status %d\n", status);
|
||||||
|
|
||||||
|
if (status > 0) {
|
||||||
|
cell->payload.stream.meta = make_cons(
|
||||||
|
make_cons(status_key,
|
||||||
|
make_integer(status, NIL)),
|
||||||
|
cell->payload.stream.meta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Callback to assemble metadata for a URL stream. This is naughty because
|
* Callback to assemble metadata for a URL stream. This is naughty because
|
||||||
* it modifies data, but it's really the only way to create metadata.
|
* it modifies data, but it's really the only way to create metadata.
|
||||||
*/
|
*/
|
||||||
static size_t write_meta_callback( void *ptr, size_t size, size_t nmemb,
|
static size_t write_meta_callback( char *string, size_t size, size_t nmemb,
|
||||||
struct cons_pointer stream ) {
|
struct cons_pointer stream ) {
|
||||||
struct cons_space_object *cell = &pointer2cell( stream );
|
struct cons_space_object *cell = &pointer2cell( stream );
|
||||||
|
|
||||||
|
/* make a copy of the string that we can destructively change */
|
||||||
|
char * s = calloc(strlen(string), sizeof(char));
|
||||||
|
|
||||||
|
strcpy( s, string);
|
||||||
|
|
||||||
if ( strncmp( &cell->tag.bytes[0], READTAG, 4 ) ||
|
if ( strncmp( &cell->tag.bytes[0], READTAG, 4 ) ||
|
||||||
strncmp( &cell->tag.bytes[0], WRITETAG, 4 ) ) {
|
strncmp( &cell->tag.bytes[0], WRITETAG, 4 ) ) {
|
||||||
char *s = ( char * ) ptr;
|
int offset = index_of( ':', s );
|
||||||
int offset = index_of( ':', ptr );
|
|
||||||
|
|
||||||
if ( offset != -1 ) {
|
if ( offset != -1 ) {
|
||||||
s[offset] = ( char ) 0;
|
s[offset] = ( char ) 0;
|
||||||
|
@ -293,18 +327,43 @@ static size_t write_meta_callback( void *ptr, size_t size, size_t nmemb,
|
||||||
c_string_to_lisp_string( wvalue ) ),
|
c_string_to_lisp_string( wvalue ) ),
|
||||||
cell->payload.stream.meta );
|
cell->payload.stream.meta );
|
||||||
|
|
||||||
|
free(wname);
|
||||||
|
free(wvalue);
|
||||||
|
|
||||||
debug_printf( DEBUG_IO,
|
debug_printf( DEBUG_IO,
|
||||||
L"write_meta_callback: added header '%s': value '%s'\n",
|
L"write_meta_callback: added header '%s': value '%s'\n",
|
||||||
name, value );
|
name, value );
|
||||||
|
} else if (strncmp( "HTTP", s, 4) == 0) {
|
||||||
|
int offset = index_of( ' ', s );
|
||||||
|
char *value = trim( &s[offset] );
|
||||||
|
wchar_t *wvalue = calloc( strlen( value ), sizeof( wchar_t ) );
|
||||||
|
mbstowcs( wvalue, value, strlen( value ) );
|
||||||
|
|
||||||
|
cell->payload.stream.meta =
|
||||||
|
make_cons( make_cons
|
||||||
|
( c_string_to_lisp_keyword( L"status" ),
|
||||||
|
c_string_to_lisp_string( wvalue ) ),
|
||||||
|
cell->payload.stream.meta );
|
||||||
|
|
||||||
|
maybe_add_status_meta( cell);
|
||||||
|
|
||||||
|
debug_printf( DEBUG_IO,
|
||||||
|
L"write_meta_callback: added header 'status': value '%s'\n",
|
||||||
|
value );
|
||||||
|
} else {
|
||||||
|
debug_printf( DEBUG_IO,
|
||||||
|
L"write_meta_callback: header passed with no colon: '%s'\n",
|
||||||
|
s );
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
debug_print
|
debug_print
|
||||||
( L"Pointer passed to write_meta_callback did not point to a stream: ",
|
( L"Pointer passed to write_meta_callback did not point to a stream: ",
|
||||||
DEBUG_IO );
|
DEBUG_IO );
|
||||||
debug_dump_object( stream, DEBUG_IO );
|
debug_dump_object( stream, DEBUG_IO );
|
||||||
}
|
}
|
||||||
|
|
||||||
return nmemb;
|
free(s);
|
||||||
|
return strlen(string);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -351,7 +410,7 @@ lisp_open( struct stack_frame *frame, struct cons_pointer frame_pointer,
|
||||||
|
|
||||||
if ( stringp( frame->arg[0] ) ) {
|
if ( stringp( frame->arg[0] ) ) {
|
||||||
struct cons_pointer meta =
|
struct cons_pointer meta =
|
||||||
make_cons( make_cons( c_string_to_lisp_keyword( L"url" ),
|
make_cons(make_cons( c_string_to_lisp_keyword( L"url" ),
|
||||||
frame->arg[0] ),
|
frame->arg[0] ),
|
||||||
NIL );
|
NIL );
|
||||||
|
|
||||||
|
@ -366,13 +425,13 @@ lisp_open( struct stack_frame *frame, struct cons_pointer frame_pointer,
|
||||||
result = make_write_stream( stream, meta );
|
result = make_write_stream( stream, meta );
|
||||||
}
|
}
|
||||||
|
|
||||||
free( url );
|
|
||||||
|
|
||||||
if ( pointer2cell( result ).payload.stream.stream == NULL ) {
|
if ( pointer2cell( result ).payload.stream.stream == NULL ) {
|
||||||
result = NIL;
|
result = NIL;
|
||||||
} else {
|
} else {
|
||||||
collect_meta( result, frame->arg[0] );
|
collect_meta( result, frame->arg[0] );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free( url );
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|
|
@ -328,6 +328,12 @@ struct cons_pointer make_write_stream( URL_FILE * output,
|
||||||
struct cons_pointer c_string_to_lisp_keyword( wchar_t *symbol ) {
|
struct cons_pointer c_string_to_lisp_keyword( wchar_t *symbol ) {
|
||||||
struct cons_pointer result = NIL;
|
struct cons_pointer result = NIL;
|
||||||
|
|
||||||
|
for (int i = 0; symbol[i] != '\0'; i++) {
|
||||||
|
if(iswalpha(symbol[i] && !iswlower(symbol[i]))) {
|
||||||
|
symbol[i] = towlower(symbol[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for ( int i = wcslen( symbol ); i > 0; i-- ) {
|
for ( int i = wcslen( symbol ); i > 0; i-- ) {
|
||||||
result = make_keyword( symbol[i - 1], result );
|
result = make_keyword( symbol[i - 1], result );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue