Improvements to URL metadata collection
Still not perfect - some corruption of data.
This commit is contained in:
parent
2258b13cc9
commit
eb49ca4e2d
73
src/io/io.c
73
src/io/io.c
|
@ -1,7 +1,10 @@
|
|||
/*
|
||||
* 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>
|
||||
* Licensed under GPL version 2.0, or, at your option, any later version.
|
||||
|
@ -24,6 +27,8 @@
|
|||
#include "consspaceobject.h"
|
||||
#include "debug.h"
|
||||
#include "fopen.h"
|
||||
#include "integer.h"
|
||||
#include "intern.h"
|
||||
#include "lispops.h"
|
||||
|
||||
/**
|
||||
|
@ -264,18 +269,47 @@ char *trim( char *s ) {
|
|||
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
|
||||
* 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_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 ) ||
|
||||
strncmp( &cell->tag.bytes[0], WRITETAG, 4 ) ) {
|
||||
char *s = ( char * ) ptr;
|
||||
int offset = index_of( ':', ptr );
|
||||
int offset = index_of( ':', s );
|
||||
|
||||
if ( offset != -1 ) {
|
||||
s[offset] = ( char ) 0;
|
||||
|
@ -293,9 +327,33 @@ static size_t write_meta_callback( void *ptr, size_t size, size_t nmemb,
|
|||
c_string_to_lisp_string( wvalue ) ),
|
||||
cell->payload.stream.meta );
|
||||
|
||||
free(wname);
|
||||
free(wvalue);
|
||||
|
||||
debug_printf( DEBUG_IO,
|
||||
L"write_meta_callback: added header '%s': value '%s'\n",
|
||||
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 {
|
||||
debug_print
|
||||
|
@ -304,7 +362,8 @@ static size_t write_meta_callback( void *ptr, size_t size, size_t nmemb,
|
|||
debug_dump_object( stream, DEBUG_IO );
|
||||
}
|
||||
|
||||
return nmemb;
|
||||
free(s);
|
||||
return strlen(string);
|
||||
}
|
||||
|
||||
|
||||
|
@ -366,13 +425,13 @@ lisp_open( struct stack_frame *frame, struct cons_pointer frame_pointer,
|
|||
result = make_write_stream( stream, meta );
|
||||
}
|
||||
|
||||
free( url );
|
||||
|
||||
if ( pointer2cell( result ).payload.stream.stream == NULL ) {
|
||||
result = NIL;
|
||||
} else {
|
||||
collect_meta( result, frame->arg[0] );
|
||||
}
|
||||
|
||||
free( url );
|
||||
}
|
||||
|
||||
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 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-- ) {
|
||||
result = make_keyword( symbol[i - 1], result );
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue