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)));