|
|
|
#define INSTANCE_OF(A,B) (object_program((A)) == object_program((B)) || \ |
Program.inherits(object_program((A)), \ |
object_program(B))) |
|
|
|
|
|
class Params |
{ |
|
protected array(Param) params; |
|
|
|
|
protected void create(Param ... args) |
{ |
params = args||({}); |
} |
|
|
|
|
|
string sign(string secret) |
{ |
return md5(sort(params)->name_value()*"" + secret); |
} |
|
|
array(string) _indices() |
{ |
return params->get_name(); |
} |
|
|
array(string) _values() |
{ |
return params->get_value(); |
} |
|
|
array(Param) get_params() |
{ |
return params; |
} |
|
string to_unencoded_query() |
{ |
return params->name_value()*"&"; |
} |
|
|
string to_query() |
{ |
array o = ({}); |
foreach (params, Param p) |
o += ({ urlencode(p->get_name()) + "=" + urlencode(p->get_value()) }); |
|
return o*"&"; |
} |
|
|
mapping(string:mixed) to_mapping() |
{ |
return mkmapping(params->get_name(), params->get_value()); |
} |
|
|
|
|
|
|
|
this_program add_mapping(mapping value) |
{ |
foreach (value; string k; mixed v) |
params += ({ Param(k, (string)v) }); |
|
return this; |
} |
|
|
|
|
|
|
|
this_program `+(Param|this_program p) |
{ |
if (mappingp(p)) { |
foreach (p; string k; string v) { |
params += ({ Param(k, v) }); |
} |
|
return this; |
} |
|
if (INSTANCE_OF(p, this)) |
params += p->get_params(); |
else |
params += ({ p }); |
|
return this; |
} |
|
|
|
|
this_program `-(Param|this_program p) |
{ |
if (!p) return this; |
|
array(Param) the_params; |
if (INSTANCE_OF(p, this)) |
the_params = p->get_params(); |
else |
the_params = ({ p }); |
|
return object_program(this)(@(params-the_params)); |
} |
|
|
|
|
|
Param `[](string key) |
{ |
foreach (params, Param p) |
if (p->get_name() == key) |
return p; |
|
return 0; |
} |
|
|
this_program clone() |
{ |
return object_program(this)(@params); |
} |
|
|
|
|
string _sprintf(int t) |
{ |
return t == 'O' && sprintf("%O(%O)", object_program(this), params); |
} |
|
|
|
|
mixed cast(string how) |
{ |
switch (how) { |
case "mapping": return to_mapping(); |
case "string": return to_query(); |
} |
} |
} |
|
|
|
|
|
|
|
|
|
|
class Param |
{ |
|
protected string name; |
|
|
protected string value; |
|
|
|
|
|
protected void create(string _name, mixed _value) |
{ |
name = _name; |
low_set_value((string)_value); |
} |
|
|
string get_name() |
{ |
return name; |
} |
|
|
|
|
void set_name(string _name) |
{ |
name = _name; |
} |
|
|
string get_value() |
{ |
return value; |
} |
|
|
|
|
void set_value(mixed _value) |
{ |
low_set_value((string)_value); |
} |
|
|
string name_value() |
{ |
return name + "=" + value; |
} |
|
|
string name_value_encoded() |
{ |
return urlencode(name) + "=" + urlencode(value); |
} |
|
|
|
|
int(0..1) `==(mixed other) |
{ |
if (!INSTANCE_OF(this, other)) return 0; |
if (name == other->get_name()) |
return value == other->get_value(); |
|
return 0; |
} |
|
|
|
|
int(0..1) `>(mixed other) |
{ |
if (!INSTANCE_OF(this, other)) return 0; |
if (name == other->get_name()) |
return value > other->get_value(); |
|
return name > other->get_name(); |
} |
|
|
|
|
int(0..1) `<(mixed other) |
{ |
if (!INSTANCE_OF(this, other)) return 0; |
if (name == other->get_name()) |
return value < other->get_value(); |
|
return name < other->get_name(); |
} |
|
|
|
|
string _sprintf(int t) |
{ |
return t == 'O' && sprintf("%O(%O,%O)", object_program(this), name, value); |
} |
|
mixed cast(string how) |
{ |
switch (how) |
{ |
case "string": return name_value_encoded(); |
} |
|
error("Cant cast %O() to %O\n", this_program, how); |
} |
|
|
|
|
private void low_set_value(string v) |
{ |
value = v; |
|
if (String.width(value) < 8) { |
if (mixed e = catch(value = string_to_utf8(value))) { |
werror("Warning: Auth.low_set_value(%O): string_to_utf8() failed. " |
"Already encoded?\n%s\n", value, describe_error(e)); |
} |
} |
} |
} |
|
|
|
|
|
string urlencode(string s) |
{ |
#if constant(Protocols.HTTP.uri_encode) |
return Protocols.HTTP.uri_encode(s); |
#elif constant(Protocols.HTTP.http_encode_string) |
return Protocols.HTTP.http_encode_string(s); |
#endif |
} |
|
|
|
|
|
string urldecode(string s) |
{ |
#if constant(Protocols.HTTP.uri_decode) |
return Protocols.HTTP.uri_decode(s); |
#elif constant(Protocols.HTTP.http_decode_string) |
return Protocols.HTTP.http_decode_string(s); |
#else |
return s; |
#endif |
} |
|
|
|
|
mapping query_to_mapping(string query) |
{ |
mapping m = ([]); |
if (!query || !sizeof(query)) |
return m; |
|
if (query[0] == '?') |
query = query[1..]; |
|
foreach (query/"&", string p) { |
sscanf (p, "%s=%s", string k, string v); |
m[k] = urldecode(v); |
} |
|
return m; |
} |
|
|
|
|
string md5(string s) |
{ |
#if constant(Crypto.MD5) |
return String.string2hex(Crypto.MD5.hash(s)); |
#else |
return Crypto.string_to_hex(Crypto.md5()->update(s)->digest()); |
#endif |
} |
|
|