diff --git a/_examples/file-server/embedding-files-into-app/bindata.go b/_examples/file-server/embedding-files-into-app/bindata.go index e5dd7e67..2290ae5a 100644 --- a/_examples/file-server/embedding-files-into-app/bindata.go +++ b/_examples/file-server/embedding-files-into-app/bindata.go @@ -85,12 +85,12 @@ func assetsCssBootstrapMinCss() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "assets/css/bootstrap.min.css", size: 141513, mode: os.FileMode(438), modTime: time.Unix(1497526846, 0)} + info := bindataFileInfo{name: "assets/css/bootstrap.min.css", size: 141513, mode: os.FileMode(438), modTime: time.Unix(1499700236, 0)} a := &asset{bytes: bytes, info: info} return a, nil } -var _assetsFaviconIco = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\x62\x60\x60\x64\x60\x64\x10\x10\x00\xd1\x0a\x0c\x19\x2c\x0c\x0c\x62\x0c\x0c\x0c\x1a\x0c\x0c\x0c\x02\x0c\x0c\x0c\x0a\x0c\x10\x71\x30\x60\x61\x60\x10\xe6\x86\xe0\xe1\x02\x26\x1a\xb3\x30\x75\x18\xb2\x71\x36\x9a\xf2\x73\x4c\x31\x67\x67\x68\x33\xe4\x60\x68\xd4\x61\xe3\x68\x37\xe2\xe4\x68\x35\xe4\x60\x58\x6a\xc1\xcc\x30\xcf\x9c\x95\x61\x82\x39\x17\x53\xa6\x89\x04\x43\xbd\xa9\x00\x43\x95\x89\x20\x43\x87\x39\x3f\x4b\xa3\xa9\x00\x73\xb8\x9b\x99\x45\x8e\xb3\xfa\xbc\x72\x0b\xf1\xd0\x28\x5b\x1d\x06\x2b\x67\x67\xbe\x4c\x4f\xfd\xb6\x52\x33\xf1\x96\x26\x43\x6e\xc9\x64\x2b\x15\x06\x57\x3b\x0b\x91\x02\x33\x49\xb7\x16\x13\x1e\xbe\x78\x73\x65\x06\x5d\x47\x0f\xce\x0c\x5b\x95\xd4\x5a\x53\x41\xf5\x8e\x62\x8f\x92\x45\x35\x4e\x7f\xca\xec\x64\x33\xba\xd3\xad\x18\x32\x62\x9c\x13\x8a\x62\x6c\x5f\x36\xc5\x99\xbd\x2d\xb1\x92\x5a\xda\xa0\xc7\xa9\xe9\xe9\xe3\xac\x9d\xee\xa6\xbb\xa7\xca\x44\x30\xb2\x26\xc5\x81\xa1\x38\xcd\xc3\xa5\x35\xc1\xfc\x5e\x99\x91\x90\xcb\xd4\x1a\xaf\xa8\x8d\x6d\x2e\xdf\xca\x6c\xa4\x63\x2d\xdd\xdc\x84\x26\x96\xba\x1e\x2b\xf2\xd6\x99\x38\xb5\xda\x73\xc5\xfc\x0a\x87\x9f\xe5\x8e\x0a\x7b\xf3\x8c\x25\x1c\xcb\x92\x1c\x37\x96\x3b\x2b\x1d\x4a\x53\xe2\x56\x9d\xdf\xec\x33\x7d\x75\xbd\xe3\x8f\x22\x13\xb1\x98\x96\x22\x4f\xfb\xc5\xd5\x8e\x6f\x0a\xcd\x24\x42\x3a\xcb\xbc\x52\x97\xd5\x3b\x7f\xcc\xb7\x96\xf3\xf5\xf1\x75\x51\xde\x3a\xd1\xf7\xf2\x92\x6a\xc7\x2f\xe9\x06\x12\x5e\xf5\x79\x9e\xb1\xbd\x19\x56\xef\x72\x6d\x14\x17\x4d\xab\x74\x7f\xb0\xac\xce\xf9\x4f\xb9\x8d\x74\x59\x71\x86\xa7\xe6\x94\x7c\xbb\xdb\x19\xa6\x32\x91\x2b\xbb\x7c\xb7\x2e\xae\xb0\xfb\x5a\x60\x20\x9c\xca\xc0\xa0\xcd\x36\xa7\xde\x73\xd3\xc4\x3c\xbb\xcd\xb6\x02\x7c\xdc\x9e\xde\x4e\xd2\x4b\x5b\x3c\x2f\x4f\xcc\xb7\xff\xd9\x96\x6a\x7d\xbf\x3f\xcf\xfe\x61\xad\x9b\xd2\xe4\xe8\x68\x0f\x89\xfa\x04\xab\x43\x45\xe6\x92\x6e\x95\xd9\x1e\xc1\x73\x6a\xdc\x9e\x56\xba\xab\x9c\xc8\x77\x56\x0b\xed\xc8\x73\x3e\x9d\xe1\xa6\xeb\x98\xe8\x67\xc1\xf0\xff\xff\x76\x86\xe9\x35\x9e\x1d\x27\xe6\xf8\xfd\xaf\x0f\x33\x98\x5b\x99\xe4\x30\xa5\xca\x4b\x7d\x95\x93\x97\x2b\x77\x7a\x88\x75\x6d\x91\xb5\xac\xca\xff\x3b\x06\x0c\x39\x89\x6e\x7e\x45\x91\x56\x27\x53\xdd\xf4\xb7\xa4\x07\x59\x36\x38\x31\x30\xb0\xc4\xa9\x8b\x33\x14\xa5\xb8\x32\xe4\x25\xba\x5a\xcc\xaf\x73\x7b\x54\xec\xaa\x16\x1e\x19\xec\xe4\x9a\xe9\xa1\xdf\x6a\x60\xed\xc0\xe4\xe9\x66\x27\x1d\x6a\xa3\xcb\x6a\xa1\x6b\xc0\xc0\xc0\xa0\xc5\xe8\xe5\xe5\x68\xe8\xee\x62\xeb\x6e\x6f\x69\x26\xe8\xe8\x64\x07\x4e\x27\xaa\x06\x36\x0c\x36\x0e\x0e\x5c\xd1\x41\x0e\x41\x31\x36\x5a\xfc\x16\x0e\x8e\x3c\xae\x4e\x36\x72\x98\x29\xea\x3f\x1a\x1e\xde\xe0\xff\x7f\x04\x96\xec\x61\x60\x10\xe8\x60\x60\x10\xe0\x40\x53\x94\xc0\xc0\x20\x00\xc2\x0f\x18\x18\x7e\xfe\x47\xd5\x03\x08\x00\x00\xff\xff\x7d\x81\x4f\xc1\x7e\x04\x00\x00") +var _assetsFaviconIco = []byte("\x1f\x8b\x08\x00\x00\x00\x00\x00\x00\xff\xec\x5a\x0b\x70\x55\xc7\x79\xde\x7b\xce\x45\x12\xb2\x90\xc4\xc3\xe6\x61\x3b\x90\xf8\x31\xc4\x19\x6c\x32\xe3\xc4\x34\xe3\xc6\x34\x6d\xed\xd4\x69\x62\x32\x49\x9a\xa6\x75\xea\x36\x33\xee\xd8\x9e\xb4\x75\xdc\x7a\xa6\xc5\x31\x02\xa6\xd3\x84\x47\x28\x6f\x3b\xc6\x3c\xcc\xeb\x9e\xbd\x08\x21\x04\x92\x28\x12\x0e\x08\x5b\x3c\xec\x02\x92\x78\x08\x21\x09\x41\x25\x24\x10\xe8\x71\xb5\xe7\xdc\xd7\xb9\xf7\xef\xfc\xff\x9e\x73\x74\x25\xdd\x97\x24\x82\x33\x1e\xce\xcc\x3f\x7b\xee\x9e\xdd\xff\xff\xf6\xdf\x7f\xff\xfd\xf7\xdf\xcb\x98\x8b\xa9\x2c\x3f\x1f\xcb\x19\xec\x15\x37\x63\x5f\x67\x8c\xcd\x98\x21\x7f\x6b\xf9\x8c\x6d\x72\x33\x36\x7b\xb6\xf5\xfb\x11\xc6\x9e\xbd\x97\xb1\x99\x8c\xb1\x7c\x6c\xc7\x64\x3d\x3d\x6e\x76\xdb\x1f\xe1\x75\xab\x42\x53\x7e\x22\x3c\x6c\x91\xf0\xb0\x02\x22\xae\x14\x08\x8f\xab\x40\xec\x64\x92\xf0\x5d\x53\xfe\x59\xec\x64\x5f\x15\x1e\xa6\x08\x4f\x7f\x7f\xdf\x7a\x96\xa1\x97\x3c\xb8\x3f\x78\xfa\x0d\x08\x9e\x5d\x08\xc1\xda\x5f\x82\x51\xf6\x65\x30\xca\x67\x41\xf0\xcc\xbf\x11\x19\x07\x1e\x07\xbd\x78\x2a\x18\x65\x8f\xb5\x0b\x4d\x7d\xad\x6f\x07\x73\x0b\xcd\x45\xfd\xbb\x17\xb3\x0c\xa3\x62\xce\xfe\xa8\xd1\x0a\xf8\x98\x6d\x25\x10\x38\xfe\x53\x88\xdc\x3a\x01\x66\x6b\x11\x11\xbe\x07\x8e\xfd\x2d\x84\x2e\x2c\x05\xff\xd1\x79\x3d\xc2\xc3\x7e\x20\x78\x06\x13\x5c\x89\xe9\xdf\x06\xd1\x50\x2f\x04\x4e\xfc\x0c\xcc\x6b\xa5\x60\x1c\xfd\x21\x74\x6c\x1e\x47\x84\xef\x58\x17\xf8\xe4\x65\x30\x6f\x54\x81\x71\xe0\x89\xea\xbe\x2d\x6c\xd2\x80\xfe\xfe\x76\x30\x6f\x1c\x81\x60\xed\x7c\x08\x9e\x5d\x0c\x2d\xeb\xc7\x41\xed\xd2\x29\x50\xbb\x74\x32\xbd\x63\x1d\x7e\xc3\x36\xa1\x73\xff\x19\x14\x1e\x36\x4f\x78\xc7\xc4\xf4\xef\x80\x70\xd3\xfb\x10\x6e\x5c\x0f\xdd\x65\x73\xe1\xdc\xf2\x89\xd0\xb1\x25\x0f\x6e\x7c\x90\x07\xe7\x7f\x33\x81\xea\xf0\x5b\xb8\x79\x13\x61\xd0\x8b\xa7\x2c\x09\x7c\xfc\x57\xac\x7b\x11\xf6\x7f\x6a\x5f\xd4\xb8\x06\xa1\xfa\x15\x10\x6e\x7a\x0f\x3a\xb4\xc7\xa0\x61\x55\x3e\x04\x8f\xfc\x39\x84\x3e\xfa\x4b\x68\x5c\x93\x4f\x75\xf8\x2d\x74\x71\x05\x44\x45\x13\xea\x54\xeb\x7c\x85\xa9\x48\xf8\x1e\x15\xcd\xf4\xcd\xee\x7f\x71\x65\x3e\x04\x3e\x7c\x86\x78\x5c\x5a\x1d\xd3\xbf\x7e\x05\xa0\x2c\x94\x89\xb2\x03\xd5\x3f\x66\x88\x05\x31\x21\x36\x1b\xff\xd9\xe5\x13\xe1\xda\xc6\x5c\x68\xdf\x94\x4b\x63\x71\xf0\x37\xbd\x0f\x38\x56\x1c\x33\x8e\x1d\x75\x80\xba\x40\x9d\x0c\xd6\x5f\xcd\x92\x29\x44\x83\xf5\x87\xba\x76\xfa\x73\x85\xe1\x5c\x18\x07\x9e\x38\x86\x18\x68\x8e\xac\xf9\xbb\xbe\x39\x87\xc8\x99\xbf\x13\x3f\xa3\x39\xc6\xb9\x8e\xed\x4f\xb6\xe0\x61\x3f\x40\xdb\x40\x1b\x41\x5b\x19\x62\x3f\xc7\x7f\x4a\xb6\x85\x0f\xda\x9a\xdd\x9f\xd6\x80\xe6\x62\xd2\x26\xd5\xd7\xd0\x46\xc9\x56\x0f\x3c\xde\x6f\xbf\xe5\xb3\xc8\xa6\xd1\xb6\xc9\xc6\x4f\xbf\x01\x68\xf3\x68\xfb\xce\x3a\xf2\x30\x26\x76\x32\x85\xd6\x08\xae\x95\xc1\xeb\x87\xd6\x14\xb3\x69\x11\xad\x39\xaf\x5b\x1d\xed\xfa\x05\x60\x8c\x65\x32\xc6\x54\x8b\x5c\x31\x64\x3d\x0b\x63\xe8\xb0\x45\x2d\x56\xdf\x99\x96\x8f\x99\x1b\xeb\x67\xf2\x47\x8b\xea\xf3\xf9\x08\xae\x22\xe5\x09\xae\x4e\x17\x5c\xfd\xc2\x28\x69\x8a\xe0\xca\x58\xb4\x3d\xdb\x17\xa6\x29\xff\x5f\x04\x57\x5b\x85\xe6\xba\x92\x90\xb8\x1a\x43\x4a\x4c\xbd\x62\xd7\xb7\x08\xae\xd6\x0b\xae\xfe\x8f\xe0\xea\x9b\x38\x1e\x1f\x1f\x4b\xfe\x34\xb5\x7c\xa5\x40\xec\xca\x02\xbd\x64\x3a\xe8\xfb\xbe\x38\x94\x4a\xa6\x83\xf0\x66\x82\xd0\x14\x10\x9a\x0b\x44\xe1\x38\x5c\x2b\x44\xf8\x4e\x75\x5c\x01\xe1\x75\x03\xf2\x11\x9a\x2b\x2a\xb8\x52\x2b\xb8\x3a\x4f\x68\x8a\x92\x0c\x03\xc9\xf7\xb0\x02\xa3\xfc\x2b\x10\xe9\xae\x85\xa8\x7e\x15\xa2\xfa\x95\x18\xba\x0a\xa1\xb3\x8b\x49\xbe\xbe\xe7\x5e\x08\xfe\xef\x3f\x81\xd9\x51\x09\x91\xbe\x4b\x44\xf8\x8e\x75\xf8\x4d\x70\x37\x04\x3e\xfe\x11\xf9\x14\xbd\x68\x3c\xe2\xe8\x14\x5c\x7d\x49\x78\x99\x2b\x11\x06\x47\xfe\x81\xd9\x10\x0d\xde\x82\xc1\x8f\x79\xe3\x30\xe8\x7b\xa7\x81\x51\xfa\x28\x98\xd7\xca\x00\xa2\xa6\xfc\x80\x65\xcc\x3b\x7e\xc3\x36\xfa\xde\x07\x08\x93\xd9\x5a\x0c\xfa\xfe\x87\x41\x68\xac\x43\x70\xf5\x59\x92\xe3\x1d\xea\x1a\x92\xc9\x8f\x06\x3a\xc1\xff\xe1\x5c\xda\x67\x91\x27\x3e\x91\xde\x0b\xe4\xaf\xfc\x47\x5f\x20\xc2\x77\xac\x23\xac\x1d\x95\xd4\xd6\xff\xe1\x9f\x10\x2f\xfa\x5d\xf2\x05\xc4\x70\x4c\x70\xf5\x7e\x94\x35\x1c\xf9\xa1\xc6\x77\x68\x3e\x43\x17\x57\x4a\xfe\xe8\xc3\xcb\xbe\x8c\xfc\xa0\xcf\x23\x09\xdf\xb1\x0e\xbf\x51\x9f\x8b\x2b\x65\x9f\xc6\x77\xe8\x37\xee\x4f\x62\xd7\x58\xb4\x8f\x05\x3e\x9e\x35\xc4\x1e\x13\xc9\x8f\x06\xbb\xc0\xa8\xfc\x23\xf0\x1f\xfa\x63\x88\x86\xba\x21\x72\xeb\x24\x18\xfb\x1f\x82\xde\x1d\x2e\x68\xdd\x30\x0e\x1a\x56\x4f\x24\xc2\x77\xac\xc3\x6f\xd8\x06\xdb\x62\x1f\xec\x8b\xef\x10\xd6\xc1\xff\xd1\xf7\x11\x67\x83\xe0\xea\x97\x06\xeb\x20\x91\x7c\xd2\xdd\xee\x3c\x08\x37\x6f\x04\x30\x0d\x08\x7c\x34\x8f\xe4\x34\xae\x99\x00\xa7\x7f\x3d\x0d\x4e\xfd\xea\x7e\x22\x7c\xc7\x3a\xfc\x86\x6d\xb0\x6d\xb8\x69\x23\xf5\xb5\xe7\xcc\x6c\x3f\x00\x62\x77\x6e\x54\x68\xae\x57\xad\xf5\x96\x52\x7e\xb0\x6e\x01\xe8\xfb\x66\xd0\x1a\x30\xaf\x95\x83\x28\xcc\x81\x2b\xef\xe6\x92\x3c\x24\x8a\x63\x96\x4d\x71\x7e\xe3\x37\x6c\x83\x6d\xb1\x0f\xf6\x0d\xd6\x15\x48\x5d\x86\x7c\x64\x47\xc2\xc3\xf6\x0a\xae\x66\xc6\xea\x20\xae\xfc\x48\x08\xfc\x55\xdf\x05\x7f\xd5\x77\x00\x22\x41\x08\x7e\xfa\x2a\x74\x6d\x53\xa1\x6e\xf9\x64\x92\x75\x69\xcd\x44\xb8\xb9\x35\x13\x6e\x6d\xcb\x80\xe6\x75\xe3\xa9\x0e\xbf\x61\x1b\x6c\x8b\x7d\xb0\xaf\xbf\xea\x7b\xc4\x8b\xec\xe2\xec\x22\x9c\x83\x66\xc1\xd5\x19\xa9\xe4\xd3\xdc\x1f\x98\x0d\xc1\x33\x6f\x42\x34\xec\x03\x7f\xe5\x1c\x68\xdb\x30\x96\xe4\x9c\xfb\xcd\x7d\xd0\xbd\x63\x0c\xe8\x85\x63\x41\x2f\xbc\x07\x7a\x3d\x6e\xa8\x5f\x39\x89\xbe\x61\x1b\x6c\x8b\x7d\xb0\xaf\xe4\xd9\x65\xd9\x6e\x19\x88\x5d\xd9\xba\xd0\x5c\x73\x53\xca\xd7\xff\x0f\xf4\xfd\x0f\x41\xa8\x61\x35\xf9\x1f\x7d\xdf\x74\x68\x5e\x97\x47\xf3\xdd\xf2\x4e\x1e\xc9\x0d\x9f\xfc\x3b\x30\x4f\xbd\x02\xc6\x9e\x09\xd0\xba\x21\x07\x4e\xfd\x6a\x1a\xb5\xc1\xb6\xe4\xb3\x1a\x56\x13\x0f\xe4\x25\xd7\xed\x39\x5c\x9b\x51\xa1\xb1\x17\xe3\xc8\x7f\x0b\x63\x13\x5c\xef\xd4\xb6\xaf\x91\x7c\x6b\xf8\xf2\x16\x5a\xdb\x62\xcf\x64\xb8\xb4\x7a\x3c\xc9\x68\xdb\x90\x0d\xfe\xb2\x87\x01\x2e\x2d\x07\x68\x5a\x05\x81\xca\x27\xe1\xfa\xe6\x4c\x39\x2f\xab\xc7\x53\xdb\x88\xaf\x9e\xfa\x22\x0f\xe4\xe5\xc4\x47\xa5\x8f\xa2\x0d\xfc\x22\x8e\xfc\x5f\xe0\x37\x3b\x5e\x4f\x2e\xff\x1e\xf0\x97\x7e\x11\xa2\x0d\x4b\x00\x9a\x56\x42\xe0\xe0\x13\x70\x7d\x53\x56\x6a\xf9\x81\x4e\x8a\xbf\x70\xac\x43\xe4\x6b\xec\x45\xd4\x0d\xea\x28\xbe\xfe\x67\x38\xfa\x6f\x5e\x97\x2f\xfd\xcb\xd1\xe7\x21\x74\xec\x87\xa0\xef\xce\x81\xab\xbf\x1d\x67\x7d\xcb\xb3\xd6\xcc\x50\xfd\xe3\xdc\xe2\x1c\xcb\xb3\xd0\x60\xf9\xae\xb9\x68\x1b\xe4\xdf\x53\xd8\x1f\xda\x39\xda\xbe\xee\x55\x41\xf7\xba\xc9\x16\xcf\xaf\xb8\x2f\xa5\xfd\x25\x95\x8f\x6b\x42\x63\xcd\xb8\xcf\x25\x5c\x7f\x5b\xe5\xfa\xc3\x39\xb8\xf0\xdf\xf7\x42\xfb\xc6\x7b\xa0\x63\x53\x36\x5c\x5c\x35\x29\xad\xf5\x97\x42\x7e\x26\xfa\x06\xda\x37\xc2\xbe\xb4\xfc\x0f\xd2\x99\x25\xd3\xd2\xf2\x3f\xc9\xe5\x2b\xf6\x1c\xbc\x86\x3e\x12\x7d\xe5\x50\xff\xeb\x8f\xe3\x7f\x25\x0d\xf5\xbf\xfe\x21\xfe\x37\x99\xfc\x18\x1d\x7c\x09\xf7\x08\xdc\x2b\xc0\xd4\x69\xef\x30\x2a\x46\xb9\xff\x58\x73\x9f\x5a\xbe\xc2\x7c\x1a\xed\x8d\x0b\x70\xaf\xc4\x3d\x53\xee\xbf\xef\x8e\x7a\xff\x4d\x47\x7e\x8c\x0e\xee\xc7\x58\x01\x63\x06\xd4\x1d\xf6\x41\x9b\x18\x51\xfc\x61\xf9\xb2\xb4\xe5\x7b\x55\x1b\xc3\xb3\x18\x33\x61\xec\x84\x31\x14\xf1\xdc\xfb\x40\x5a\xf1\x97\x4e\xf1\xd7\x34\x8a\xd9\x06\x3f\xa9\xe4\x3b\xb6\x48\xb1\xa2\xfa\x12\xc6\x8e\x18\x43\x62\x2c\x89\x31\x25\xc6\x96\x29\xe3\x4f\x6f\x26\xc5\xaa\xf1\x62\x58\x8c\x6d\x31\xc6\x4d\x26\xbf\x7f\x3d\x60\xcc\xac\xce\xa3\x18\x1a\x63\x69\x8c\xa9\xb9\x5b\xc6\xd8\x14\x7f\xe7\xc4\xc4\xdf\x39\xb2\x0e\x63\x73\x8c\x91\x93\xc5\xf0\xc4\x47\x49\x2a\x9f\x30\x68\x0a\xf3\x15\x65\x31\x6b\xaf\x7e\xd3\x3a\x53\xd4\x5b\x67\x8c\x44\xe7\x0f\x49\xc9\xcf\x30\xad\xd6\x59\x27\xa9\xfc\x58\x5d\xf4\x69\x14\x2f\x8d\x95\x67\xab\x51\x9f\xcf\xa6\x5b\x67\xbd\xb4\xe4\x7f\xde\x1f\x7b\x6d\x1c\x66\x2a\x1c\x66\x0c\xe9\x99\xc3\x8c\x4d\xb7\x28\xcf\xa2\x4c\x8b\xd4\x74\xa8\xc5\xa2\x1e\x8b\x02\x16\x99\x8c\xa9\xc0\x48\x90\x6a\xcb\x9d\xc9\x18\x9b\xcd\x18\xfb\xfb\xd8\x3c\xc5\xc3\x9f\xb5\x56\xee\x3e\x77\x9f\x3f\xcc\xc7\xda\x1f\x1f\x16\x5c\x7d\x5b\x70\x75\xa1\xe0\x6a\xc1\xef\x89\x6c\xde\xff\x2a\xb8\xfa\x37\x82\x2b\xb3\x05\x57\x72\x7a\x35\xc6\x0c\x2d\x79\x3e\x29\x0d\xfc\xdf\x16\x5c\x0d\x0a\xae\xc2\x1d\x22\x53\x70\xb5\x53\x70\xf5\x20\xed\xeb\x5c\xc9\xc7\x58\xc3\x48\x33\x3f\x97\x18\xbf\x42\xb1\x57\x5a\x84\x6d\x07\x60\x4a\xd2\x37\x6e\x5b\x97\xfd\x1b\xf5\x56\x2a\xb8\xfa\x24\xec\x67\x4c\xe7\xc3\x1b\x83\x83\x5f\x73\x05\x31\xc6\x0b\xd6\xbe\x45\xe7\xf2\x64\x14\x3c\xbb\x08\x8c\x8a\xa7\xfa\x71\x21\xc6\xc2\x1c\x30\x0e\x7e\x0d\x02\x27\xfe\x81\x78\x20\xe1\x3b\xd6\xc9\x78\x84\x39\xd8\xf5\xe2\x29\x60\x94\xcd\x04\xe1\xcd\x8a\x1d\x47\xa3\xe0\xea\x0b\x7e\xce\x5c\x7a\x8a\xfc\x64\x7c\xfc\x2c\x48\xf1\x75\xb8\x6f\x48\x9c\x37\xf8\x31\xdb\x4a\x64\x9c\x84\xb2\xbd\x19\xe0\x3f\xf2\x17\x60\xb6\xee\x85\x68\xe0\x26\x40\x34\x12\x13\x20\x46\xa8\x0e\xbf\x61\x1b\x6c\x8b\x7d\xf4\xe2\xc9\x10\x6a\x58\x0b\xe1\xcb\x5b\xc1\xa8\xfc\x46\xff\x9c\x70\xb5\x0d\xc7\xd0\xa3\x65\x33\x91\xe6\x3c\x0c\x17\x7f\xa4\xeb\x14\xc5\xb4\xc2\xc3\xe8\x3c\x43\xb1\x65\xb0\x3b\xe5\x98\xb1\x0d\xb6\xc5\x3e\xf2\x7c\x30\x13\x22\xdd\x35\x10\xf5\x5f\xa7\x73\xa9\x28\xbc\xc7\x1e\x43\x93\xe0\xca\x53\x14\x73\x16\xa6\x8e\x89\x86\x83\x9f\xce\x41\x55\xdf\x23\xec\x62\x77\x2e\x9d\xc7\xed\xb3\xa8\x1c\x5c\x10\xa2\xa2\x05\x22\xb7\x3e\x21\xc2\x77\xac\xeb\xff\x1e\xa2\x3e\xd8\x17\x79\x20\xaf\x68\xa8\x87\xda\x84\xea\x97\xcb\xbc\xb3\x1c\x43\xa5\xe0\xea\xe4\x74\x62\xba\xe1\xe0\x0f\x35\xac\x91\x36\xc0\xdd\x10\xac\x7b\xbb\x1f\x7b\x34\x0c\x66\x47\x05\xdd\x3d\xe9\xa5\x8f\x80\x5e\x34\x51\x52\xe9\x23\xf2\x3e\xaa\xa3\x82\xda\xd8\x63\x08\xd6\xfe\x52\xc6\xee\xde\x0c\xe2\x69\x8f\x1d\xcf\x4d\x92\xbf\x1a\x45\x7f\xeb\xf3\x32\x57\x5f\x0a\x3b\x4a\x17\x3f\xea\xd2\x28\x9f\x25\xf5\x76\xe4\x3b\xfd\x79\xad\x70\x1f\x84\xce\xff\x17\xe8\x7b\x26\x59\xfe\xc6\xca\xdb\xdb\x3e\x46\x63\xf4\x0d\xdb\xd8\xbc\xe9\x0c\x78\xe4\x79\xe2\x85\x3c\x69\x9e\x68\x7e\x7b\x21\x50\xfd\x63\x7b\x4d\x5f\x13\x5c\xfd\x7a\xca\x73\x45\x9a\xf8\x69\x7e\xad\xb5\x67\xde\xa8\xea\xd7\x59\xdd\x02\x79\x0f\xc1\xa5\x1f\xe9\xd9\x39\x06\x6e\x6e\xcd\x22\xc2\x77\xb9\x36\x5d\xd4\x06\xdb\xda\xf6\x64\xde\x38\x42\xbc\x90\x27\xf2\x76\x4c\xac\xbb\x86\x72\x44\xd6\x18\xde\xd3\xb9\xcb\x9d\xcc\x1f\xa5\x83\x9f\xf2\x5c\x15\x73\x48\x5f\x81\x4f\x5f\x75\xce\xa8\xe1\xcb\x5b\x1c\x9b\x45\xac\x57\xde\xcd\xa3\x5c\x66\xcd\xd2\x29\x44\xf8\x8e\x75\x72\x1c\x0a\xb5\xc5\x3e\x92\xa9\x49\xbc\x68\x0e\x2a\xe6\x0c\x38\x5b\x87\x2e\x2c\xb1\xce\x86\x6a\xbb\xe0\xea\x57\x93\x9f\x2d\x53\xe3\xa7\x5c\xcf\xae\x6c\xb2\x03\xb3\xb3\x5a\xea\xa9\xaf\x51\x9e\x5d\x35\x06\xdd\xdb\x33\x9c\x9c\x53\x3c\xc2\x6f\xd8\x86\xfc\x4e\xf9\x57\x9c\xfc\x9f\xd9\xf9\xb1\xb4\xbb\xc2\x6c\x30\xdb\xcb\xfb\xf5\xa5\x5f\x95\x79\x41\xb9\x67\x2c\x12\xdc\x9d\xf0\xce\x2a\x1d\xfc\xe4\xdf\xc8\x5f\x7c\x97\x72\xf1\x54\x57\xf3\xef\x64\x17\xbd\x1e\x37\xe5\x6c\x12\x61\xb7\x09\xdb\x60\x5b\xec\x83\x7d\xe5\x00\x0c\xe2\x89\xbc\x51\xc6\x00\x99\x75\x0b\x6d\x1b\x3a\x2e\xb8\x32\x61\xa4\xf8\xf1\x37\xe5\xe9\x35\x06\xa1\x86\x55\x96\x7e\x5a\xc0\x28\x9d\x49\x75\xad\xef\x8d\x1b\x82\xb5\x76\xd9\xc0\x7b\x00\x9b\xb0\xad\xed\xfb\xa3\xfa\x15\x69\x2b\x17\x57\x51\x1d\xca\x88\x95\x8d\xfe\x57\xde\x9f\x29\x3e\xc1\xd5\x6f\x26\xce\x8f\x24\xc7\x1f\xf1\x35\x80\x5e\xf2\x00\xe8\xbb\xf3\x21\x72\xf3\x98\x65\xf7\x1f\x80\xf0\x8e\x81\x9e\x1d\x63\xc8\xc6\x6d\x7c\x35\x4b\xa7\x92\xbd\xdf\xda\x96\x09\x5d\xdb\x33\xa1\x6d\x43\x8e\x73\xbf\x60\xe7\xf9\xb1\x0f\xfa\x48\xdc\x7b\x89\xff\xcd\x6a\xe2\x4d\x79\x65\x5f\xc3\x40\xbd\xfd\xee\x5b\xb6\x0d\x51\x7e\x3b\xde\x3a\x4e\x85\xdf\xec\x38\x44\xb6\x6f\x94\x3d\x46\xff\x67\xc0\x27\x70\xf2\x65\xe2\x7b\xed\xfd\x9c\x98\xbc\xe7\x54\xa9\x5f\x27\x16\x50\x40\xe7\x2a\x5c\xdf\x9c\x4d\xf7\x32\x76\x3b\xec\x83\x7d\x03\x9f\xfc\xa3\xc4\xe9\x6f\x27\xde\x28\x03\x65\x0d\xb0\xa1\x9a\xff\xb0\xf1\x6f\xd3\xb9\x2b\xee\x9d\x69\x2a\xfc\xa4\x6b\x9c\xdf\xc3\xcf\x01\x44\x02\x94\xcb\x35\x2a\x9f\xa6\xba\xa6\xb5\x13\x9c\x7c\x29\xae\x51\x9f\x47\xe6\x93\xf4\xc2\x6c\xd0\x77\x8f\x73\xe2\xcd\xcb\xeb\xf3\x9d\xfc\x2a\xf6\x21\x7e\x87\x9e\x96\x79\xe1\x48\x80\x78\x63\x1d\xca\x1a\x20\xfb\x2a\xb7\xf7\xb3\x6a\xc1\x95\xdc\x91\xe0\x0f\x5d\x58\x26\xfd\xe6\xf1\x97\xa4\xbe\xc4\x65\xca\x5d\xf5\xee\x54\x29\xe7\x6d\xeb\xb5\x0d\xf5\xca\x5d\x60\xec\x9d\x4a\x77\x30\x91\xda\x37\xc0\x5f\x3e\x93\xc6\xd3\xf9\xc1\x58\xb2\x2d\x3b\x4f\xee\xdb\xa9\x12\x0f\xe4\x45\xf3\x79\xfc\x25\x92\x81\xb2\x06\xd8\xee\xcd\x13\xf2\xce\x98\x2b\x4d\x82\xab\x0f\x26\xc9\x91\x3e\x97\x08\x3f\xed\x4f\x3b\x19\x04\x4f\xbd\x2e\x79\xf6\xd4\xd2\xbe\xd3\xbd\x7d\x0c\x9c\xb5\x6c\x1b\xb1\xe1\x7e\xa5\x7b\x55\x08\x1d\xfb\x11\x40\xf3\x5a\x22\xf3\xf4\xcf\x69\x2e\xd0\xff\xa3\xed\x23\x7e\xec\xd3\xbd\xdd\x4d\x31\x74\xa4\xa7\x4e\xca\x38\xf5\xba\x94\x81\xfb\x5b\xac\xef\x10\xcd\x74\xf7\x64\xdd\x79\xcf\x4a\x82\xff\x5b\x42\x63\x86\x71\xf0\xc9\x21\xb1\x24\xf9\x4e\xe4\x5d\x3b\xdf\xd2\xc9\x71\xd0\x8b\xf2\xa1\x6b\x5b\x86\xe3\x63\xb0\xec\xda\x9e\x41\xf7\x6f\x66\xcd\xeb\x00\xcd\x6b\x00\x9a\x56\x43\xb4\x7e\x31\x18\x7b\x27\x83\xcf\x23\xe7\x0a\xf1\x3b\x6d\x8b\xf2\xe9\xff\x3a\x24\xa3\x76\xbe\x94\x31\xc8\x87\x62\x6c\x4a\x31\x8b\xc6\xfa\x04\x57\x9f\x4e\x82\xff\x69\x6c\x43\xb1\x88\xff\xfa\xc8\xf0\x6f\xcb\x00\x7d\x57\x16\x98\x67\x7e\xde\x8f\xff\x42\x01\x18\xc5\x93\x08\xff\xf9\x91\xe0\x0f\x76\x03\xea\x14\x75\x4b\x3a\x4e\x8c\x7f\x16\xe5\x96\xf7\xcd\xa0\x39\x4b\x6e\x3f\x75\x34\xf7\x68\x03\xb6\xfd\xa0\xef\xb9\xb1\x85\xee\xd3\x21\x78\xe4\xcf\xe8\x0e\x10\xed\x27\x7c\xe2\x45\xd0\xbd\x19\xd0\xbd\x23\x83\xda\x0e\xdb\x7e\xc2\x7d\x74\x67\x81\xb6\x4d\x36\x9e\x18\xff\x83\xb8\x46\xf4\xa2\x09\x74\xdf\x31\x92\xf5\x7b\xf5\xb7\xb9\x96\xef\xc9\x81\x60\xd5\x73\x10\xaa\xfe\x3e\xe8\xc5\xf7\x82\xce\x15\xba\xd3\xc2\x31\x9e\xfa\xb5\xbd\x7e\x95\xb4\xd6\xef\x20\xfc\xdf\x8e\x8f\x9f\x72\xeb\xb9\xe4\xa3\x70\x5f\xb9\xca\x07\xf0\x48\xd7\x7f\x9e\x5b\x81\x7b\x53\x46\x7f\xec\x6c\x91\x4f\xeb\x8f\x2f\xb0\x6d\xe3\x30\xfc\x67\xba\xf8\xe5\xde\xa0\x6e\x47\x1e\xc1\x9a\xf9\x03\x78\xa4\xbb\x7f\x21\x35\xad\x1b\x0f\xbd\x9e\x31\xd6\x3d\xa6\x0a\x7d\x9a\x9b\xe6\x05\x75\x3f\x64\xff\x3a\xf9\xb2\xb5\x46\x13\xef\x5f\xe9\xe0\xd7\xed\xbb\x3e\xdc\xa3\x51\x2f\xbf\xfb\xd3\x81\x71\x48\xdc\xf8\x61\x6b\xdc\xf8\xc1\xde\xc7\x30\x6e\x40\x9c\xa8\xeb\x58\xec\xc3\x89\x1f\xd2\xc5\x1f\xb3\x06\xbe\x29\xb8\xd2\xa7\xef\xb9\x0f\x22\x5d\x9f\x0e\xe0\xe1\xc4\x6f\x17\xd3\x8b\xdf\x12\xd1\x70\xe2\xb7\xe1\xe1\xa7\x35\x30\x81\x62\x55\xcd\x45\xe7\xd0\xd8\xe7\xb3\x88\x9f\x87\x85\x5f\x53\x18\xfd\x3f\x95\xab\x8b\xe5\x19\xe3\x71\x3a\x43\x38\x6b\xe0\xf7\x76\x7e\xa9\x8e\x7b\x7e\x19\x2e\xfe\x18\x1b\xc2\xb3\x5a\x07\x9e\xdd\xf0\x0c\xe7\xf0\xb9\x23\xe7\xc7\x9b\xa3\xc4\x4f\x7e\xc8\x8d\x67\x66\x3a\xa7\xef\x7f\x88\xce\xd2\xf6\x93\xf6\xf9\x7d\x47\xcc\xf9\x7d\x47\xb2\xf3\x7b\x55\xdc\xf3\xfb\x48\xf1\xc7\xcc\xc1\xd7\x28\x77\x81\x3e\xae\xfa\xaf\x29\xa7\x01\x43\xf2\x27\xcf\x0f\xcc\x9f\x9c\xbb\x3d\xf9\x93\xd1\xe2\xef\xe3\x2e\xe6\xe3\x4c\x91\x67\x66\x35\x8a\x7e\x8e\xd6\xb2\xa5\xb3\xd4\xf9\xab\x17\xc1\x28\x7d\x04\xf4\x3d\x13\x89\x8c\x44\xf9\xab\xba\xb7\x87\xe6\xaf\x6e\x03\xfe\x98\x39\x98\x2c\xb8\x7a\xc8\xb6\xd9\x50\xfd\x32\x99\x1b\x0c\xf5\x38\xfe\xe2\xf6\xe5\x0f\x13\xe7\x4e\x47\x84\xbf\x50\xb5\xfd\xe9\x1c\x2b\x97\x4a\xb9\x55\xfa\xdf\x50\xe0\x3a\x44\xba\xcf\xc8\xdc\x37\xda\x8a\x9d\xbf\x4d\x82\xc1\xc1\x62\xe5\x6f\xb1\x0f\xe5\x7e\x4b\x1f\xa5\x5c\x70\xd2\x3e\x23\xc0\x4f\x63\xf0\xba\x58\x8f\x27\x1b\xe7\xe1\x05\x99\xd3\x56\x68\xbe\x8d\xca\x6f\xd0\xbe\x19\x6a\x58\xeb\xac\x3d\x27\x7f\xde\x56\x92\x7e\xfe\xbc\xe4\x41\x30\xdb\xf6\xa5\x1e\xf3\x08\xf1\xe3\xa3\x7b\x15\x66\xec\xa2\xff\x6d\xbc\x60\xdd\x2d\x48\xbc\xbb\xb2\xe8\xbf\x31\x7a\xf1\xd4\x24\xf7\x17\xf3\x89\x12\xdd\x5f\x18\x15\x4f\xd1\x1d\x48\xca\x7b\x92\xda\xb7\xac\xff\xda\xba\x86\x8d\x9f\xc6\xc0\x5d\x0c\xbc\xe4\x5b\xd1\x27\x95\x39\x77\x64\x8e\x8f\x19\xcd\xfd\xd1\xb0\xee\xa9\x46\x84\x1f\x1f\x43\x73\xd9\x6b\x7a\xbc\xbc\x6b\xa3\x3b\xb7\x4e\xeb\x0e\xee\x4e\xdd\xf7\x8d\x18\xbf\x33\x0e\x8f\xc2\x7a\x8b\x54\x8c\x35\x72\x04\x57\x67\x0b\xae\xfe\xc4\xba\x0b\x2d\xb8\x03\xf7\xae\x6f\x5b\x77\xbc\x23\xc6\x7f\xf7\xb9\xfb\x7c\x9e\x1e\xb9\x43\x24\x2e\x5b\x18\x63\xcf\x58\x65\x9e\x55\x66\x5a\xa5\x6b\x50\xc9\xec\xb2\xc0\x2a\x9f\x19\x54\x4e\x4f\x50\xe6\x25\x28\x33\x6f\x5f\xd9\x93\xa0\x0c\x24\x28\xcd\x41\x65\xd4\x2a\xc1\x2e\x17\x0e\x2a\x5b\xac\xb2\xc7\x2a\x4d\xab\x4c\xa1\xdf\xff\x0f\x00\x00\xff\xff\xc6\xb9\x24\x2f\xee\x3a\x00\x00") func assetsFaviconIcoBytes() ([]byte, error) { return bindataRead( @@ -105,7 +105,7 @@ func assetsFaviconIco() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "assets/favicon.ico", size: 1150, mode: os.FileMode(438), modTime: time.Unix(1498241946, 0)} + info := bindataFileInfo{name: "assets/favicon.ico", size: 15086, mode: os.FileMode(438), modTime: time.Unix(1496572980, 0)} a := &asset{bytes: bytes, info: info} return a, nil } @@ -125,7 +125,7 @@ func assetsJsJquery211Js() (*asset, error) { return nil, err } - info := bindataFileInfo{name: "assets/js/jquery-2.1.1.js", size: 256541, mode: os.FileMode(438), modTime: time.Unix(1497526846, 0)} + info := bindataFileInfo{name: "assets/js/jquery-2.1.1.js", size: 256541, mode: os.FileMode(438), modTime: time.Unix(1499700236, 0)} a := &asset{bytes: bytes, info: info} return a, nil } diff --git a/_examples/mvc/session-controller/main.go b/_examples/mvc/session-controller/main.go index 4a294353..f3460639 100644 --- a/_examples/mvc/session-controller/main.go +++ b/_examples/mvc/session-controller/main.go @@ -23,7 +23,8 @@ func (u *VisitController) Get() { u.Session.Set("visits", visits) // write the current, updated visits - u.Ctx.Writef("%d visits in %0.1f seconds", visits, time.Now().Sub(u.StartTime).Seconds()) + u.Ctx.Writef("%d visit from my current session in %0.1f seconds of server's up-time", + visits, time.Now().Sub(u.StartTime).Seconds()) } func main() { diff --git a/_examples/sessions/database/badger/data/000000.vlog b/_examples/sessions/database/badger/data/000000.vlog new file mode 100644 index 00000000..9b5be5ec Binary files /dev/null and b/_examples/sessions/database/badger/data/000000.vlog differ diff --git a/_examples/sessions/database/badger/data/000001.sst b/_examples/sessions/database/badger/data/000001.sst new file mode 100644 index 00000000..6b3fed50 Binary files /dev/null and b/_examples/sessions/database/badger/data/000001.sst differ diff --git a/_examples/sessions/database/badger/data/000002.sst b/_examples/sessions/database/badger/data/000002.sst new file mode 100644 index 00000000..ce341a4f Binary files /dev/null and b/_examples/sessions/database/badger/data/000002.sst differ diff --git a/_examples/sessions/database/badger/data/000003.sst b/_examples/sessions/database/badger/data/000003.sst new file mode 100644 index 00000000..f01aec51 Binary files /dev/null and b/_examples/sessions/database/badger/data/000003.sst differ diff --git a/_examples/sessions/database/badger/data/000004.sst b/_examples/sessions/database/badger/data/000004.sst new file mode 100644 index 00000000..840c9b16 Binary files /dev/null and b/_examples/sessions/database/badger/data/000004.sst differ diff --git a/_examples/sessions/database/badger/data/MANIFEST b/_examples/sessions/database/badger/data/MANIFEST new file mode 100644 index 00000000..c4f5aa42 Binary files /dev/null and b/_examples/sessions/database/badger/data/MANIFEST differ diff --git a/core/errors/reporter.go b/core/errors/reporter.go index 859993a2..3a4ebf86 100644 --- a/core/errors/reporter.go +++ b/core/errors/reporter.go @@ -56,23 +56,33 @@ func NewReporter() *Reporter { // AddErr adds an error to the error stack. // if "err" is a StackError then // each of these errors will be printed as individual. -func (r *Reporter) AddErr(err error) { +// +// Returns true if this "err" is not nil and it's added to the reporter's stack. +func (r *Reporter) AddErr(err error) bool { if err == nil { - return + return false } if stackErr, ok := err.(StackError); ok { r.addStack(stackErr.Stack()) - return + } else { + r.mu.Lock() + r.wrapper = r.wrapper.AppendErr(err) + r.mu.Unlock() } - r.mu.Lock() - r.wrapper = r.wrapper.AppendErr(err) - r.mu.Unlock() + return true } // Add adds a formatted message as an error to the error stack. -func (r *Reporter) Add(format string, a ...interface{}) { +// +// Returns true if this "err" is not nil and it's added to the reporter's stack. +func (r *Reporter) Add(format string, a ...interface{}) bool { + + if format == "" && len(a) == 0 { + return false + } + // usually used as: "module: %v", err so // check if the first argument is error and if that error is empty then don't add it. if len(a) > 0 { @@ -81,7 +91,7 @@ func (r *Reporter) Add(format string, a ...interface{}) { Error() string }); ok { if e.Error() == "" { - return + return false } } } @@ -89,6 +99,7 @@ func (r *Reporter) Add(format string, a ...interface{}) { r.mu.Lock() r.wrapper = r.wrapper.Append(format, a...) r.mu.Unlock() + return true } // Describe same as `Add` but if "err" is nil then it does nothing. diff --git a/core/router/api_builder.go b/core/router/api_builder.go index faff3cc5..921f70fa 100644 --- a/core/router/api_builder.go +++ b/core/router/api_builder.go @@ -545,12 +545,6 @@ func (api *APIBuilder) Controller(relativePath string, controller activator.Base api.reporter.Add("%v for path: '%s'", err, relativePath) } - if cInit, ok := controller.(interface { - Init(activator.RegisterFunc) - }); ok { - cInit.Init(registerFunc) - } - return } diff --git a/context.go b/go19.go similarity index 95% rename from context.go rename to go19.go index bec37e4c..47c85d01 100644 --- a/context.go +++ b/go19.go @@ -9,13 +9,6 @@ import ( "github.com/kataras/iris/mvc" ) -// TODO: When go 1.9 will be released -// split this file in order to separate the concepts. -// -// Files should change after go1.9 final release: -// README.md: Hello World with Go 1.9 -// core/host/supervisor.go -// context.go type ( // Context is the midle-man server's "object" for the clients. // diff --git a/mvc/activator/activate_listener.go b/mvc/activator/activate_listener.go new file mode 100644 index 00000000..708d08fc --- /dev/null +++ b/mvc/activator/activate_listener.go @@ -0,0 +1,78 @@ +package activator + +import ( + "reflect" +) + +// CallOnActivate simply calls the "controller"'s `OnActivate(*ActivatePayload)` function, +// if any. +// +// Look `activator.go#Register` and `ActivateListener` for more. +func CallOnActivate(controller interface{}, + bindValues *[]interface{}, registerFunc RegisterFunc) { + + if ac, ok := controller.(ActivateListener); ok { + p := &ActivatePayload{ + BindValues: bindValues, + Handle: registerFunc, + } + ac.OnActivate(p) + } +} + +// ActivateListener is an interface which should be declared +// on a Controller which needs to register or change the bind values +// that the caller-"user" has been passed to; via the `app.Controller`. +// If that interface is completed by a controller +// then the `OnActivate` function will be called ONCE, NOT in every request +// but ONCE at the application's lifecycle. +type ActivateListener interface { + // OnActivate accepts a pointer to the `ActivatePayload`. + // + // The `Controller` can make use of the `OnActivate` function + // to register custom routes + // or modify the provided values that will be binded to the + // controller later on. + // + // Look `ActivatePayload` for more. + OnActivate(*ActivatePayload) +} + +// ActivatePayload contains the necessary information and the ability +// to alt a controller's registration options, i.e the binder. +// +// With `ActivatePayload` the `Controller` can register custom routes +// or modify the provided values that will be binded to the +// controller later on. +type ActivatePayload struct { + BindValues *[]interface{} + Handle RegisterFunc +} + +// EnsureBindValue will make sure that this "bindValue" +// will be registered to the controller's binder +// if its type is not already passed by the caller.. +// +// For example, on `SessionController` it looks if *sessions.Sessions +// has been binded from the caller and if not then the "bindValue" +// will be binded and used as a default sessions manager instead. +// +// At general, if the caller has already provided a value with the same Type +// then the "bindValue" will be ignored and not be added to the controller's bind values. +// +// Returns true if the caller has NOT already provided a value with the same Type +// and "bindValue" is NOT ignored therefore is appended to the controller's bind values. +func (i *ActivatePayload) EnsureBindValue(bindValue interface{}) bool { + valueTyp := reflect.TypeOf(bindValue) + localBindValues := *i.BindValues + + for _, bindedValue := range localBindValues { + // type already exists, remember: binding here is per-type. + if reflect.TypeOf(bindedValue) == valueTyp { + return false + } + } + + *i.BindValues = append(localBindValues, bindValue) + return true +} diff --git a/mvc/activator/activator.go b/mvc/activator/activator.go index 740a1c8f..64d11000 100644 --- a/mvc/activator/activator.go +++ b/mvc/activator/activator.go @@ -65,7 +65,6 @@ type BaseController interface { // ActivateController returns a new controller type info description. func ActivateController(base BaseController, bindValues []interface{}) (TController, error) { - // get and save the type. typ := reflect.TypeOf(base) if typ.Kind() != reflect.Ptr { @@ -202,6 +201,8 @@ func RegisterMethodHandlers(t TController, registerFunc RegisterFunc) { func Register(controller BaseController, bindValues []interface{}, registerFunc RegisterFunc) error { + CallOnActivate(controller, &bindValues, registerFunc) + t, err := ActivateController(controller, bindValues) if err != nil { return err diff --git a/mvc/controller_test.go b/mvc/controller_test.go index 4d81525b..3474b0bd 100644 --- a/mvc/controller_test.go +++ b/mvc/controller_test.go @@ -7,6 +7,7 @@ import ( "github.com/kataras/iris" "github.com/kataras/iris/context" "github.com/kataras/iris/mvc" + "github.com/kataras/iris/mvc/activator" "github.com/kataras/iris/core/router" "github.com/kataras/iris/httptest" @@ -493,3 +494,33 @@ func TestControllerRelPathFromFunc(t *testing.T) { e.GET("/anything/here").Expect().Status(httptest.StatusOK). Body().Equal("GET:/anything/here") } + +type testControllerActivateListener struct { + mvc.Controller + + TitlePointer *testBindType +} + +func (c *testControllerActivateListener) OnActivate(p *activator.ActivatePayload) { + p.EnsureBindValue(&testBindType{ + title: "default title", + }) +} + +func (c *testControllerActivateListener) Get() { + c.Text = c.TitlePointer.title +} + +func TestControllerActivateListener(t *testing.T) { + app := iris.New() + app.Controller("/", new(testControllerActivateListener)) + app.Controller("/manual", new(testControllerActivateListener), &testBindType{ + title: "my title", + }) + + e := httptest.New(t, app) + e.GET("/").Expect().Status(httptest.StatusOK). + Body().Equal("default title") + e.GET("/manual").Expect().Status(httptest.StatusOK). + Body().Equal("my title") +} diff --git a/mvc/go19.go b/mvc/go19.go new file mode 100644 index 00000000..3cfa6daf --- /dev/null +++ b/mvc/go19.go @@ -0,0 +1,19 @@ +// +build go1.9 + +package mvc + +import ( + "github.com/kataras/iris/mvc/activator" +) + +// ActivatePayload contains the necessary information and the ability +// to alt a controller's registration options, i.e the binder. +// +// With `ActivatePayload` the `Controller` can register custom routes +// or modify the provided values that will be binded to the +// controller later on. +// +// Look the `mvc/activator#ActivatePayload` for its implementation. +// +// A shortcut for the `mvc/activator#ActivatePayload`, useful when `OnActivate` is being used. +type ActivatePayload = activator.ActivatePayload diff --git a/mvc/session_controller.go b/mvc/session_controller.go index bc6adbe6..06c17f6a 100644 --- a/mvc/session_controller.go +++ b/mvc/session_controller.go @@ -2,9 +2,14 @@ package mvc import ( "github.com/kataras/iris/context" + "github.com/kataras/iris/mvc/activator" "github.com/kataras/iris/sessions" + + "github.com/kataras/golog" ) +var defaultManager = sessions.New(sessions.Config{}) + // SessionController is a simple `Controller` implementation // which requires a binded session manager in order to give // direct access to the current client's session via its `Session` field. @@ -15,21 +20,27 @@ type SessionController struct { Session *sessions.Session } -var managerMissing = "MVC SessionController: session manager field is nil, you have to bind it to a *sessions.Sessions" +// OnActivate called, once per application lifecycle NOT request, +// every single time the dev registers a specific SessionController-based controller. +// It makes sure that its "Manager" field is filled +// even if the caller didn't provide any sessions manager via the `app.Controller` function. +func (s *SessionController) OnActivate(p *activator.ActivatePayload) { + if p.EnsureBindValue(defaultManager) { + golog.Warnf(`MVC SessionController: couldn't find any "*sessions.Sessions" bindable value to fill the "Manager" field, +therefore this controller is using the default sessions manager instead. +Please refer to the documentation to learn how you can provide the session manager`) + } +} // BeginRequest calls the Controller's BeginRequest // and tries to initialize the current user's Session. func (s *SessionController) BeginRequest(ctx context.Context) { s.Controller.BeginRequest(ctx) if s.Manager == nil { - ctx.Application().Logger().Errorf(managerMissing) + ctx.Application().Logger().Errorf(`MVC SessionController: sessions manager is nil, report this as a bug +because the SessionController should predict this on its activation state and use a default one automatically`) return } s.Session = s.Manager.Start(ctx) } - -/* TODO: -Maybe add struct tags on `binder` for required binded values -in order to log error if some of the bindings are missing or leave that to the end-developers? -*/ diff --git a/sessions/sessiondb/badger/database.go b/sessions/sessiondb/badger/database.go index 7a60d182..05fcc617 100644 --- a/sessions/sessiondb/badger/database.go +++ b/sessions/sessiondb/badger/database.go @@ -22,7 +22,7 @@ type Database struct { // Service is the underline badger database connection, // it's initialized at `New` or `NewFromDB`. // Can be used to get stats. - Service *badger.KV + Service *badger.DB async bool } @@ -51,7 +51,7 @@ func New(directoryPath string) (*Database, error) { opts.Dir = directoryPath opts.ValueDir = directoryPath - service, err := badger.NewKV(&opts) + service, err := badger.Open(&opts) if err != nil { golog.Errorf("unable to initialize the badger-based session database: %v", err) @@ -62,7 +62,7 @@ func New(directoryPath string) (*Database, error) { } // NewFromDB same as `New` but accepts an already-created custom badger connection instead. -func NewFromDB(service *badger.KV) (*Database, error) { +func NewFromDB(service *badger.DB) (*Database, error) { if service == nil { return nil, errors.New("underline database is missing") } @@ -75,30 +75,37 @@ func NewFromDB(service *badger.KV) (*Database, error) { // Cleanup removes any invalid(have expired) session entries, // it's being called automatically on `New` as well. -func (db *Database) Cleanup() error { +func (db *Database) Cleanup() (err error) { rep := errors.NewReporter() - iter := db.Service.NewIterator(badger.DefaultIteratorOptions) + txn := db.Service.NewTransaction(true) + defer txn.Commit(nil) + + iter := txn.NewIterator(badger.DefaultIteratorOptions) + defer iter.Close() + for iter.Rewind(); iter.Valid(); iter.Next() { // Remember that the contents of the returned slice should not be modified, and // only valid until the next call to Next. item := iter.Item() - err := item.Value(func(b []byte) error { - storeDB, err := sessions.DecodeRemoteStore(b) - if err != nil { - return err - } + b, err := item.Value() - if storeDB.Lifetime.HasExpired() { - err = db.Service.Delete(item.Key()) - } - return err - }) + if rep.AddErr(err) { + continue + } - rep.AddErr(err) + storeDB, err := sessions.DecodeRemoteStore(b) + if rep.AddErr(err) { + continue + } + + if storeDB.Lifetime.HasExpired() { + if err := txn.Delete(item.Key()); err != nil { + rep.AddErr(err) + } + } } - iter.Close() return rep.Return() } @@ -112,21 +119,28 @@ func (db *Database) Async(useGoRoutines bool) *Database { // Load loads the sessions from the badger(key-value file-based) session storage. func (db *Database) Load(sid string) (storeDB sessions.RemoteStore) { bsid := []byte(sid) - iter := db.Service.NewIterator(badger.DefaultIteratorOptions) - defer iter.Close() - iter.Seek(bsid) - if !iter.Valid() { + txn := db.Service.NewTransaction(false) + defer txn.Discard() + + item, err := txn.Get(bsid) + if err != nil { + // Key not found, don't report this, session manager will create a new session as it should. return } - item := iter.Item() - item.Value(func(b []byte) (err error) { - storeDB, err = sessions.DecodeRemoteStore(b) // decode the whole value, as a remote store - if err != nil { - golog.Errorf("error while trying to load from the remote store: %v", err) - } + + b, err := item.Value() + + if err != nil { + golog.Errorf("error while trying to get the serialized session(%s) from the remote store: %v", sid, err) return - }) + } + + storeDB, err = sessions.DecodeRemoteStore(b) // decode the whole value, as a remote store + if err != nil { + golog.Errorf("error while trying to load from the remote store: %v", err) + } + return } @@ -155,19 +169,28 @@ func (db *Database) sync(p sessions.SyncPayload) { golog.Errorf("error while serializing the remote store: %v", err) } - // err = db.Service.Set(bsid, s, meta) - e := &badger.Entry{ - Key: bsid, - Value: s, - } - err = db.Service.BatchSet([]*badger.Entry{e}) + txn := db.Service.NewTransaction(true) + + err = txn.Set(bsid, s, 0x00) if err != nil { - golog.Errorf("error while writing the session(%s) to the database: %v", p.SessionID, err) + txn.Discard() + golog.Errorf("error while trying to save the session(%s) to the database: %v", p.SessionID, err) + return + } + if err := txn.Commit(nil); err != nil { // Commit will call the Discard automatically. + golog.Errorf("error while committing the session(%s) changes to the database: %v", p.SessionID, err) } } func (db *Database) destroy(bsid []byte) error { - return db.Service.Delete(bsid) + txn := db.Service.NewTransaction(true) + + err := txn.Delete(bsid) + if err != nil { + return err + } + + return txn.Commit(nil) } // Close shutdowns the badger connection.