1 module itsdangerous.urlsafe; 2 3 import std.stdio; 4 5 import std.range; 6 import std.json; 7 import std.base64; 8 import std.digest.sha; 9 import std.zlib: compress, uncompress; 10 import std.algorithm.searching; 11 12 import itsdangerous.exc; 13 import itsdangerous.encoding; 14 import itsdangerous.dsigner; 15 import itsdangerous.serializer; 16 import itsdangerous.timed; 17 18 class URLSafeSerializerTemplate(SerializerType) : SerializerType { 19 20 this(string secretKey, string salt = "itsdangerous"){ 21 super(secretKey, salt); 22 //signer = makeSigner(salt); 23 } 24 25 override JSONValue loadPayload(string payload){ 26 string _json; 27 bool decompress = false; 28 if (payload.startsWith(".")){ 29 payload.popFront; 30 decompress = true; 31 } 32 try{ 33 _json = base64Decode(payload); 34 }catch (Base64Exception e){ 35 auto bpl = new BadPayload("Could not base64 decode the payload because of an exception"); 36 bpl.originalError = e.msg; 37 throw bpl; 38 } 39 if (decompress){ 40 try{ 41 _json = cast(string)uncompress(_json); 42 }catch (Exception e){ 43 auto bpl = new BadPayload("Could not zlib decompress the payload before decoding the payload"); 44 bpl.originalError = e.msg; 45 throw bpl; 46 } 47 } 48 return super.loadPayload(_json); 49 } 50 51 override string dumpPayload(JSONValue obj){ 52 string json = super.dumpPayload(obj); 53 bool is_compressed = false; 54 string compressed = cast(string)compress(json); 55 const jlen = json.length; 56 if (compressed.length < (jlen - 1)){ 57 json = compressed; 58 is_compressed = true; 59 } 60 61 string base64d = base64Encode(json); 62 if (is_compressed) 63 base64d = '.' ~ base64d; 64 return base64d; 65 } 66 } 67 68 alias URLSafeSerializer = URLSafeSerializerTemplate!(Serializer!(Signer!(SHA1, SHA1))); 69 alias URLSafeTimedSerializer = URLSafeSerializerTemplate!(TimedSerializer!(TimestampSigner!(SHA1, SHA1)));