2001-03-05
2001-03-05 18:18:41 by Per Hedbor <ph@opera.com>
-
387fa6a77308b1bbd74fedd0999e54964dc72739
(110 lines)
(+84/-26)
[
Show
| Annotate
]
Branch: 5.2
The argcache IDs are now slightly harder to guess. Also, the index and values are stored separately
Rev: server/base_server/global_variables.pike:1.65
Rev: server/base_server/roxen.pike:1.640
4:
// Per Hedbor, Henrik Grubbström, Pontus Hagland, David Hedbor and others.
// ABS and suicide systems contributed freely by Francesco Chemolli
- constant cvs_version="$Id: roxen.pike,v 1.639 2001/03/01 20:52:52 per Exp $";
+ constant cvs_version="$Id: roxen.pike,v 1.640 2001/03/05 18:18:41 per Exp $";
// Used when running threaded to find out which thread is the backend thread.
Thread.Thread backend_thread;
554: Inside #if defined(THREADS)
"Client will not get any response from Roxen.\n"),*/
describe_backtrace(q));
if (q = catch {h = 0;}) {
- report_error(LOC_M(5, "Uncaught error in handler thread: %s Client"
+ report_error(LOC_M(5, "Uncaught error in1942 handler thread: %s Client"
"will not get any response from Roxen.")+"\n",
describe_backtrace(q));
}
2348:
case "wbf":
format = "wbmp";
case "wbmp":
- data = Image.WBF.encode( reply, enc_args );
+ Image.Colortable bw=Image.Colortable( ({ ({ 0,0,0 }),
+ ({ 255,255,255 }) }) );
+ bw->floyd_steinberg();
+ data = Image.WBF.encode( bw->map( reply ), enc_args );
break;
case "gif":
#if constant(Image.GIF) && constant(Image.GIF.encode)
2779:
return (string)db->master_sql->insert_id();
}
+ static int low_key_exists( string key )
+ {
+ return sizeof( db->query( "SELECT id FROM "+name+" WHERE id="+(int)key));
+ }
-
+ static string secret;
+
+ static void ensure_secret()
+ {
+ if( !secret )
+ secret = query( "argcache_secret" );
+ }
+ static string encode_id( string a, string b )
+ {
+ ensure_secret();
+ object crypto = Crypto.arcfour();
+ crypto->set_encrypt_key( secret );
+ string res = crypto->crypt( a+"×"+b );
+ res = Gmp.mpz( res, 256 )->digits( 36 );
+ return res;
+ }
+
+ static array decode_id( string a )
+ {
+ ensure_secret();
+ object crypto = Crypto.arcfour();
+ crypto->set_encrypt_key( secret );
+ a = Gmp.mpz( a, 36 )->digits( 256 );
+ a = crypto->crypt( a );
+ int i, j;
+ if( sscanf( a, "%d×%d", i, j ) != 2 )
+ {
+ // plugin decode here?
+ return 0;
+ }
+ return ({ (string)i, (string)j });
+ }
+
int key_exists( string key )
//! Does the key 'key' exist in the cache? Returns 1 if it does, 0
//! if it was not present.
{
- return sizeof( db->query( "SELECT id FROM "+name+" WHERE id="+(int)key));
+ array i = decode_id( key );
+ if(!i) return 0;
+ return low_key_exists( i[0] ) && low_key_exists( i[1] );
}
string store( mapping args )
2792:
//! argument cache. The string returned is your key to retrieve the
//! data later.
{
- array q;
- #if 1
+
array b = values(args), a = sort(indices(args),b);
- string data = encode_value(({a,b}));
- #else
- string data = encode_value_canonic( args );
- #endif
- if( q = cache[ data ] )
- return q[ CACHE_SKEY ];
+ string id = encode_id( low_store( a ), low_store( b ) );
+ cache[ id ] = args+([]);
+ return id;
+ }
-
+ static string low_store( array a )
+ {
+ string data = encode_value( a );
+ if( mixed q = cache[ data ] )
+ return q[ CACHE_SKEY ];
LOCK();
- if( q = cache[ data ] )
+ if( mixed q = cache[ data ] )
return q[ CACHE_SKEY ];
if( sizeof( cache ) >= CACHE_SIZE )
2824:
string id = create_key( data );
cache[ data ] = ({ 0, 0 });
- cache[ data ][ CACHE_VALUE ] = copy_value( args );
+ cache[ data ][ CACHE_VALUE ] = copy_value( a );
cache[ data ][ CACHE_SKEY ] = id;
cache[ id ] = data;
return id;
2835:
//! may be supplied to get an error message stating the browser name
//! in the event of the key not being present any more in the cache.
{
- mixed v ;
+ if( cache[id] ) return cache[id]+([]);
+ mixed v;
+ array i = decode_id( id );
+ if( !i )
+ {
+ // ID does not belong to this server. Add system for this here.
+ return 0;
+ }
+ array a = low_lookup( i[0] );
+ array b = low_lookup( i[1] );
+ if( a && b )
+ return (cache[id] = mkmapping( a, b ))+([]);
+ }
+
+ static array low_lookup( string id )
+ {
+ mixed v;
if( (v=cache[id]) && (v=cache[ v ]) )
return v[CACHE_VALUE];
-
+
string q = read_args( id );
-
+
if(!q) error("Requesting unknown key\n");
-
+
mixed data = decode_value(q);
-
- if( !mappingp( data ) )
- data = mkmapping( data[0],data[1] );
-
+
cache[ q ] = ({data,id});
cache[ id ] = q;
return data;
2856:
void delete( string id )
//! Remove the data element stored under the key 'id'.
{
+ m_delete( cache, id );
+
+ foreach( decode_id( id ), string id )
+ {
if(cache[id])
{
m_delete( cache, cache[id] );
2864:
db->query( "DELETE FROM "+name+" WHERE id="+(int)id );
}
}
+ }
mapping cached_decoders = ([]);
string decode_charset( string charset, string data )